Changed current relation from BasicBlock to BasicBlockImpl, and Function
[jitcs.git] / tests / test_asm_x86_xx_ext.lcpp
blob6bb02a348d2d034e94225dcde05f7a55b25c9419
1 #/bin/emblua LUAPREFIX=/*|
2 /*| --VARDELIM=%
3 /*| --CMTDELIM=//
4 /*| --DUMPSCRIPT=true
5 /*| --*/
6 /*| local N = $$$
7 /*| function pred_ipairs(t, pred)
8 /*|   return function(t,k)
9 /*|       local v
10 /*|       repeat
11 /*|         k = k + 1 
12 /*|         v = t[k]
13 /*|       until not v or pred(k, v)
14 /*|       return v and k, v
15 /*|     end, t or {}, 0
16 /*| end
17 /*| function isa(v) return not v[N==32 and "x64" or "x32only"] end
18 /*| function isaN(k,v) return not v[N==32 and "x64" or "x32"] end
19 #include "test_asm_x86_%(N).h"
20 #include "jitcs_machine.h"
21 #include "jitcs_tmpalloc.h"
22 #include "jitcs_memmgr.h"
23 #include "jitcs_function.h"
24 #include "jitcs_int_virtualregister.h"
26 #include <stdio.h>
28 using namespace jitcs;
30 TestAssemblerX86_%(N)::TestAssemblerX86_%(N)
31     (RefCounter<MemoryMgr> m, 
32      RefCounter<TempAllocator> a,
33      RefCounter<IMachineInfo> mi) 
34   : TestAssembler(m, a, mi) {
35   assert(mi->cpu.isX86_%(N)());
38 template <typename T> static T* unconst(const T* p) {
39   return const_cast<T*>(p);
41 bool TestAssemblerX86_%(N)::makeGR8Ref
42     (RefOrNull<const VirtualRegister>& r, std::string const& n) {
43   const VirtualRegister* v = findReg(n);
44   if (!v || !x86_%(N)::IsGR8(v->regclass)) return false;
45   r = v;
46   return true;
48 bool TestAssemblerX86_%(N)::makeGR16Ref
49     (RefOrNull<const VirtualRegister>& r, std::string const& n) {
50   const VirtualRegister* v = findReg(n);
51   if (!v || !x86_%(N)::IsGR16(v->regclass)) return false;
52   r = v;
53   return true;
55 bool TestAssemblerX86_%(N)::makeGR32Ref
56     (RefOrNull<const VirtualRegister>& r, std::string const& n) {
57   const VirtualRegister* v = findReg(n);
58   if (!v || !x86_%(N)::IsGR32(v->regclass)) return false;
59   r = v;
60   return true;
62 /*| if N == 64 then
63 bool TestAssemblerX86_%(N)::makeGR64Ref
64     (RefOrNull<const VirtualRegister>& r, std::string const& n) {
65   const VirtualRegister* v = findReg(n);
66   if (!v || !x86_%(N)::IsGR64(v->regclass)) return false;
67   r = v;
68   return true;
70 /*| end
71 bool TestAssemblerX86_%(N)::makeGRRef
72     (RefOrNull<const VirtualRegister>& r, std::string const& n) {
73   return makeGR%(N)Ref(r, n);
75 bool TestAssemblerX86_%(N)::makeVR128Ref
76     (RefOrNull<const VirtualRegister>& r, std::string const& n) {
77   const VirtualRegister* v = findReg(n);
78   if (!v || !x86_%(N)::IsVR128(v->regclass)) return false;
79   r = v;
80   return true;
82 bool TestAssemblerX86_%(N)::makeVR256Ref
83     (RefOrNull<const VirtualRegister>& r, std::string const& n) {
84   const VirtualRegister* v = findReg(n);
85   if (!v || !x86_%(N)::IsVR256(v->regclass)) return false;
86   r = v;
87   return true;
89 bool TestAssemblerX86_%(N)::makeBBRef
90     (RefOrNull<BasicBlock>& bb, std::string const& n) {
91   std::string n2 = toLower(n);
92   if (bbnames.find(n2) != bbnames.end()) {
93     bb = bbnames[n2];
94     return true;
95   }
96   Ref<BasicBlock> newbb = fnc->createBasicBlock();
97   bbnames[n2] = newbb._ptr;
98   bb = newbb._ptr;
99   return true;
101 bool TestAssemblerX86_%(N)::makei64(i64& v, std::string const& n) {
102   char* e;
103   i64 x;
104   if (n.size() >= 3 && n[0] == '0' && (n[1] | 0x20) == 'x') {
105     x = strtoll(n.c_str() + 2, &e, 16);
106   } else 
107     x = strtoll(n.c_str(), &e, 10);
108   if (e && *e) return false;
109   if (errno == ERANGE) return false;
110   v = x;
111   return true;
113 bool TestAssemblerX86_%(N)::makei8(i8& v, std::string const& n) {
114   i64 x;
115   if (!makei64(x, n)) return false;
116   if (x < -128 || x > 256-1) return false;
117   v = (i8)x;
118   return true;
120 bool TestAssemblerX86_%(N)::makei16(i16& v, std::string const& n) {
121   i64 x;
122   if (!makei64(x, n)) return false;
123   if (x < -128*256 || x > 256*256-1) return false;
124   v = (i16)x;
125   return true;
127 bool TestAssemblerX86_%(N)::makei32(i32& v, std::string const& n) {
128   i64 x;
129   if (!makei64(x, n)) return false;
130   if (x < -128*256*256*256 || x > 0xffffffff) return false;
131   v = (i32)x;
132   return true;
134 bool TestAssemblerX86_%(N)::makeMemRef
135     (RefOrNull<MemoryReference>& m, std::string const& n) {
136   if (n.substr(0,1) != "[" || n.substr(n.size()-1) != "]") return false;
137   std::vector<std::string> summands;
138   split(n.substr(1,n.size()-2), "+", summands);
139   if (summands.size() > 0) {
140     std::string p1, p2;
141     split(summands[summands.size()-1], "-", p1, p2);
142     if (p1.size() > 0 && p2.size() > 0) {
143       summands.erase(summands.begin() + summands.size() - 1);
144       summands.push_back(p1);
145       summands.push_back("-" + p2);
146     }
147   }
149   if (summands.size() < 1 || summands.size() > 3) return false;
150   // sp + o
151   // fp1..7 + o
152   std::string first = toLower(summands[0]);
153   if (first == "sp") {
154     if (summands.size() != 2) return false;
155     i32 x;
156     if (!makei32(x, summands[1])) return false;
157     Ref<MemoryReference> ptr = memstream->alloc();
158     ptr->setSPRelative(x);
159     m = ptr._ptr;
160     return true;
161   }
162   if (first.substr(0,2) == "fp") {
163     int fpno = atoi(first.c_str() + 2);
164     if (fpno < 1 || fpno > 7) return false;
165     if (summands.size() != 2) return false;
166     i32 x;
167     if (!makei32(x, summands[1])) return false;
168     Ref<MemoryReference> ptr = memstream->alloc();
169     ptr->setFPRelative(fpno, x);
170     m = ptr._ptr;
171     return true;
172   }
173   // gpr [+ gpr * s] [+ o]
174   RefOrNull<const VirtualRegister> base = nullptr, index = nullptr;
175   i32 offset = 0, scale = 1;
176   if (!makeGRRef(base, summands[0])) return false;
177   std::string q1, q2;
178   int ix = 1;
179   if (summands.size() >= 2) {
180     split(summands[1], "*", q1, q2);
181     if (q1.size() > 0 && q2.size() > 0) {
182       if (makeGRRef(index, q1) && makei32(scale, q2)) {
183         if (scale < 1 || scale > 8 || ((1 << scale) & (0x116)) == 0) return false;
184         ++ix;
185       } else if (makeGRRef(index, q2) && makei32(scale, q1)) {
186         if (scale < 1 || scale > 8 || ((1 << scale) & (0x116)) == 0) return false;
187         ++ix;
188       } else
189         return false;
190     } else if (makeGRRef(index, summands[1])) {
191       ++ix;
192     }
193   }
194   if (ix < summands.size()) {
195     if (!makei32(offset, summands[ix])) return false;
196     ++ix;
197   }
198   if (ix != summands.size()) return false;
199   {
200     Ref<MemoryReference> ptr = memstream->alloc();
201     if (index.isNull()) {
202       ptr->setBaseAndOffset(unconst(base._ptr), offset);
203     } else {
204       ptr->setBaseIndexAndOffset(unconst(base._ptr), unconst(index._ptr), scale, offset);
205     }
206     m = ptr._ptr;
207 //printf("mem: %p, %p, %d, %d\n", m._ptr->regs.base, m._ptr->regs.index, m._ptr->offset, m._ptr->modeAndScale);
208   }
209   return true;
210 }