The check to see if an item was already on the heap was randomly hitting.
[jitcs.git] / include / jitcs_x86_xx_cons.lh
blob6e07b17c48c460ae8e9fe52ebfa12b1d02057bd5
1 #/bin/emblua LUAPREFIX=/*|
2 /*| --VARDELIM=%
3 /*| --CMTDELIM=//
4 /*| --XDUMPSCRIPT=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, 0
16 /*| end
17 /*| function isa(v) return not v[N==32 and "x64" or "x32only"] end
18 //===-- jitcs_x86_%(N)_cons.h C++ -----------------------------------------*-===//
20 // Instruction constructors for %(N)bit x86 code.
22 //===----------------------------------------------------------------------===//
23 #ifndef _JITCS_X86_%(N)_CONS_H_
24 #define _JITCS_X86_%(N)_CONS_H_
26 #include "jitcs_base.h"
27 #include "jitcs_x86_%(N)_insids.h"
28 #include "jitcs_x86_%(N)_regs.h"
29 #include "jitcs_instruction.h"
30 #include "jitcs_instructionstream.h"
31 #include "jitcs_memref.h"
33 /*| local data= runfile("../src/data/x86_inslist.dat")
34 /*| --*/
36 namespace jitcs {
37 namespace x86_%(N) {
38   typedef Ref<MemoryReference> MemRef;
39   typedef Ref<const VirtualRegister> VRegRef;
40   typedef Ref<BasicBlock> BBRef;
41   typedef MemRef Mem8Ref;
42   typedef MemRef Mem16Ref;
43   typedef MemRef Mem32Ref;
44   typedef MemRef Mem64Ref;
45   typedef MemRef Mem128Ref;
46   typedef MemRef Mem256Ref;
47   typedef MemRef Mem512Ref;
49   extern const u16 ArrayInsClass2Info[x86_%(N)::ICL_Count];
50   inline uint ToSize(InsClassId icl) { return ReadFromInsClassArray(ArrayInsClass2Info, icl); }
51   inline uint ToSize(InsId id) { return ToSize(ToInsClass(id)); }
52   u32 ToValidMask(InsClassId cl);
54   static const unsigned CI64Op = sizeof(iptr) >= sizeof(i64) ? 0 : 1;
55   template <InsClassId ID> struct InsClass2SizeCT {};
56 /*| for k,cl in pred_ipairs(data.opclasses, function(k,cl) return isa(cl.isa) end) do
57 /*|   local sz, i64 = 1 + #cl.layout, 0
58 /*|   for k,v in ipairs(cl.layout) do
59 /*|     if v[1]=="Imm" and v[4] == 32 then sz = sz - 1; i64 = i64 + 1 end
60 /*|   end
61 /*|   local rsz = sz .. (i64 > 0 and (" + CI64Op * "..i64) or "")
62   template <> struct InsClass2SizeCT<ICL_%(cl.id)> { static const u8 Value = %rsz; };
63 /*| end
64 /*| --*/
65   template <InsId ID> struct Ins2SizeCT : public InsClass2SizeCT<(ToInsClassCT<ID>::Value)> {};
67   // here come the meta-constructors
68 /*| local function islowimm_org(layout,it) 
69 /*|   return it+1 <= #layout and layout[it][1] == "Imm" and layout[it+1][1] == "Imm" and layout[it][3] == layout[it+1][3]
70 /*|          and layout[it][4] == 0 and layout[it+1][4] > 0
71 /*| end
72 /*| local function islowimm(layout,it) 
73 /*|   return it+1 <= #layout and layout[it][1] == "Imm" and layout[it+1][1] == "Imm" and layout[it][2] == layout[it+1][2]
74 /*|          and layout[it][3] == 0 and layout[it+1][3] > 0
75 /*| end
76 /*| local opname2op = {}
77 /*| for k,v in ipairs(data.ops) do
78 /*|   opname2op[v.name] = v
79 /*| end
80 /*| local layouts, layoutlu, layoutlu2 = {}, {}, {}
81 /*| local function sublayout(layout)
82 /*|   local l = { sig = "" }
83 /*|   for k,v in ipairs(layout) do 
84 /*|     --if N == 64 and v[1] == "Imm" and k > 1 and islowimm_org(layout, k - 1) then
85 /*|       -- skip
86 /*|     --else
87 /*|       l[#l + 1] = {v[1],v[3],v[4]}
88 /*|       l.sig = (#l.sig > 0 and (l.sig .. ",") or "")..v[1].." "..v[3]..(v[4] and (" "..v[4]) or "")
89 /*|     --end
90 /*|   end
91 /*|   if layoutlu[l.sig] then return layoutlu[l.sig] end
92 /*|   layoutlu[l.sig] = l
93 /*|   l.id = #layouts + 1
94 /*|   layouts[l.id] = l
95 /*|   return l
96 /*| end
97 /*| for k,cl in ipairs(data.opclasses) do
98 /*|   if not layoutlu2[cl.layout.id] then
99 /*|     layoutlu2[cl.layout.id] = sublayout(cl.layout)
100 /*|   end
101 /*| end
102 /*| for id,l in ipairs(layouts) do
103 /*|   local parms = ""
104 /*|   for it,t in ipairs(l) do 
105 /*|     if not (t[1] == "Imm" and t[3] > 0) then
106 /*|       parms = parms .. ", "..(t[1] == "Imm" and (islowimm(l,it) and "i64" or "i32") 
107 /*|                               or (t[1] == "RegId" and "VRegRef")
108 /*|                               or (t[1] == "MemId" and "MemRef")
109 /*|                               or (t[1] == "BBId" and "BBRef")
110 /*|                               or t[1]) .. " " .. t[2]
111 /*|     end
112 /*|   end
113 /*| --*/
114   //layout: %(l.sig)
115   inline void _ICons%(id)(Ref<Instruction> ip, InsId id%(parms)) {
116     ip->setInsId(id);
117 /*|   for ix,t in ipairs(l) do
118 /*|     local value, fun = "", ""
119 /*|     value = t[2]
120 /*|     if t[1] == "MemId" then fun = "MRef" end
121 /*|     if t[1] == "RegId" then fun = "RRef" end
122 /*|     if t[1] == "BBId" then fun = "BB" end
123 /*|     if t[1] == "Imm" then fun = "Imm" end
124 /*|     if t[1] == "Imm" and t[3] == 32 then value = value .. (" >> "..t[3])
125     if (%(t[3]) >= sizeof(iptr))
126 /*|     end
127 /*|     if value then
128     ip->set%(fun)Op(%ix, %(value));
129 /*|     end
130 /*|   end
131   }
132 /*| end
133 /*| --*/
135   // here come the instructions
136 /*| local t2t={GR8="GR8Ref",GR16="GR16Ref",GR32="GR32Ref",GR64="GR64Ref",VR128="VR128Ref",VR256="VR256Ref",MemId="MemRef",
137 /*|            ["i8*"]="Mem8Ref",["i16*"]="Mem16Ref",["i32*"]="Mem32Ref",["i64*"]="Mem64Ref",
138 /*|            ["i128*"]="Mem128Ref",["i256*"]="Mem256Ref",["i512*"]="Mem512Ref", ["BB"]="BBRef"}
139 /*| function insparms(op)
140 /*|   local parms=""
141 /*|   for it,t in ipairs(op.operands) do 
142 /*|     if not t.fixed then
143 /*|       parms = parms .. ", "..(t2t[t.type] or t.type).." "..op.orgnames[it]
144 /*|     end
145 /*|   end
146 /*|   return parms
147 /*| end
148 /*| function relayparms(op)
149 /*|   local parms=""
150 /*|   for it,t in ipairs(op.operands) do 
151 /*|     if not t.fixed then
152 /*|       parms = parms .. ", "..op.orgnames[it]
153 /*|     end
154 /*|   end
155 /*|   return parms
156 /*| end
157 /*| function consname(op)
158 /*|   return "_ICons"..layoutlu2[op.opclass.layout.id].id
159 /*| end
160 /*| function consparms(op)
161 /*|   local ren = {}
162 /*|   for it, v in ipairs(op.operands) do
163 /*|     ren[v.name] = op.orgnames[it]
164 /*|   end
165 /*|   local parms, l = "", layoutlu2[op.opclass.layout.id]
166 /*|   for k,v in ipairs(l) do
167 /*|     if k < 2 or not islowimm(l, k - 1) then
168 /*|       parms = parms .. ", "..(ren[v[2]])
169 /*|     end
170 /*|   end
171 /*|   return parms
172 /*| end
173 /*| for k,op in pred_ipairs(data.ops, function(k,op) return isa(op.opclass.isa) end) do
174   static inline void %(op.name)(InstructionStream &is%(insparms(op))) 
175              { %(consname(op))(is.alloc(Ins2SizeCT<I_%(op.name)>::Value), I_%(op.name)%(consparms(op))); }
176 /*| end
177 /*| --*/
179 /*| local function grm(rm,n) return rm == "R" and ("GR"..n.."Ref") or ("Mem"..n.."Ref") end 
180 /*| local ccs = {"O", "NO", "B", "AE", "E", "NE", "BE", "A", "S", "NS", "PE", "PO", "L", "GE", "LE", "G"}
181 /*| local oo, tname, oname, RM
182 /*| for rm_,RM_ in ipairs{"R","M"} do
183 /*|   for k,v in pred_ipairs({{N=16,R="H"}, {N=32,R="W"}, {N=64, R="D",x64=true}},
184 /*|                          function(k,v) return v.N <= N end) do
185 /*|     RM = RM_ == "R" and v.R or "M"
186 /*|     tname, oname = "CMOVCC_" .. v.R ..RM, "CMOVO_" .. v.R .. RM
187 /*|     oo = opname2op[oname]
188 /*|     for kk,vv in ipairs(ccs) do
189   static_assert(I_%(oname) + x86_common::CC_%(vv) == I_CMOV%(vv)_%(v.R)%(RM), "X86 cmov opcode failure");
190 /*|     end
191   static inline void %(tname)(InstructionStream& is, CondCodeId cc%(insparms(oo))) { 
192     %(consname(oo))(is.alloc(Ins2SizeCT<I_%(oname)>::Value), static_cast<InsId>(I_%(oname)+cc)%(consparms(oo)));
193   }
194 /*|   end
196 /*|   RM = RM_ == "R" and "B" or "M8"
197 /*|   tname, oname = "SETCC_" .. RM, "SETO_" .. RM
198 /*|   oo = opname2op[oname]
199 /*|   for kk,vv in ipairs(ccs) do
200   static_assert(I_%(oname) + x86_common::CC_%(vv) == I_SET%(vv)_%(RM), "X86 set opcode failure");
201 /*|   end
202   static inline void %(tname)(InstructionStream& is, CondCodeId cc%(insparms(oo))) { 
203     %(consname(oo))(is.alloc(Ins2SizeCT<I_%(oname)>::Value), static_cast<InsId>(I_%(oname)+cc)%(consparms(oo)));
204   }
205 /*| end
206 /*| --*/
207 /*| tname, oname = "JCC_BB_FT", "JO_BB_FT"
208 /*| oo = opname2op[oname]
209 /*| for kk,vv in ipairs(ccs) do
210   static_assert(I_%(oname) + x86_common::CC_%(vv) == I_J%(vv)_BB_FT, "X86 jcc opcode failure");
211 /*| end
212   static inline void %(tname)(InstructionStream& is, CondCodeId cc%(insparms(oo))) { 
213     %(consname(oo))(is.alloc(Ins2SizeCT<I_%(oname)>::Value), static_cast<InsId>(I_%(oname)+cc)%(consparms(oo)));
214   }
216 /*| local al= runfile("../src/data/x86_insalias.dat")
217   // here come aliases
218 /*| for k,v in ipairs{{0,al.aliases}, {N,al["aliases"..N]}} do
219 /*|   for kk,vv in ipairs(v[2]) do
220 /*|     tname, oname = vv[1], vv[2]
221 /*|     oo = opname2op[oname]
222   static inline void %(tname)(InstructionStream& is%(insparms(oo))) { 
223     %(consname(oo))(is.alloc(Ins2SizeCT<I_%(oname)>::Value), I_%(oname)%(consparms(oo)));
224   }
225 /*|   end
226 /*| end
228 } // end of namespace jitcs::x86_%(N)
229 } // end of namespace jitcs
230 #endif
231 // _JITCS_X86_%(N)_CONS_H_