1 #/bin/emblua LUAPREFIX=/*|
7 /*| function pred_ipairs(t, pred)
8 /*| return function(t,k)
13 /*| until not v or pred(k, v)
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_memref.h"
31 #include "jitcs_bblock.h"
33 /*| local data= runfile("../src/data/x86_inslist.dat")
39 extern const u8 ArrayInsClassSizes[IC_Count - IC_Invalid - 1];
40 inline uint GetInsSize(InsId id) {
41 u32 cid = (id >> IC_SubBits);
42 assert(cid > x86::IC_Invalid && id < x86::IC_Count);
43 return ArrayInsClassSizes[cid - x86::IC_Invalid - 1];
46 template <InsClassId ID> struct InsClassSizeCT {};
47 /*| for k,cl in pred_ipairs(data.opclasses, function(k,cl) return isa(cl.isa)) do
48 /*| local sz = 1 + #cl.layout
49 /*| for k,v in ipairs(cl.layout) do
50 /*| if N == 64 and v[1]=="Imm" and v[3] == 32 then sz = sz - 1 end
53 template <> struct InsClassSizeCT<IC_%(cl.id)> {
54 static const u8 Value = %rsz;
58 template <InsId ID> struct InsSizeCT : public InsClassSizeCT<static_cast<InsClassId>(ID >> IC_SubBits)> {};
60 // here come the meta-constructors
61 /*| local function islowimm(layout,it)
62 /*| return it+1 <= #layout and layout[it][1] == "Imm" and layout[it+1][1] == "Imm" and layout[it][2] == layout[it+1][2]
63 /*| and layout[it][3] == 0 and layout[it+1][3] > 0
65 /*| local opname2op = {}
66 /*| for k,v in ipairs(data.ops) do
67 /*| opname2op[v.name] = v
69 /*| local layouts, layoutlu, layoutlu2 = {}, {}, {}
70 /*| local function sublayout(layout)
71 /*| local l = { sig = "" }
72 /*| for k,v in ipairs(layout) do
73 /*| l[#l + 1] = {v[1],v[3],v[4]}
74 /*| l.sig = (#l.sig > 0 and (l.sig .. ",") or "")..v[1].." "..v[3]..(v[4] and (" "..v[4]) or "")
76 /*| if layoutlu[l.sig] then return layoutlu[l.sig] end
77 /*| layoutlu[l.sig] = l
78 /*| l.id = #layouts + 1
82 /*| for k,cl in ipairs(data.opclasses) do
83 /*| if not layoutlu2[cl.layout.id] then
84 /*| layoutlu2[cl.layout.id] = sublayout(cl.layout)
87 /*| for id,l in ipairs(layouts) do
89 /*| for it,t in ipairs(l) do
90 /*| if not (t[1] == "Imm" and t[3] > 0) then
91 /*| parms = parms .. ", "..(t[1] == "Imm" and (islowimm(l,it) and "i64" or "i32")
92 /*| or (t[1] == "RegId" and "VRegRef")
93 /*| or (t[1] == "MemId" and "MemRef")
94 /*| or t[1]) .. " " .. t[2]
99 inline void _ICons%(id)(InsRef ip, InsId id%(parms)) {
101 /*| for ix,t in ipairs(l) do
102 /*| local value, fun = "", ""
104 /*| if t[1] == "MemId" then fun = "Mem" end
105 /*| if t[1] == "RegId" then fun = "VReg" end
106 /*| if t[1] == "BBId" then fun = "BB" end
107 /*| if t[1] == "Imm" then fun = "Imm" end
108 /*| if t[1] == "Imm" and t[3] == 32 then value = N == 32 and (value .. (" >> "..t[3])) end
110 ip.set%(fun)Op(%ix, %(value));
117 // here come the instructions
118 /*| local t2t={GR8="GR8Ref",GR16="GR16Ref",GR32="GR32Ref",GR64="GR64Ref",VR128="VR128Ref",VR256="VR256Ref",MemId="MemRef",
119 /*| ["i8*"]="Mem8Ref",["i16*"]="Mem16Ref",["i32*"]="Mem32Ref",["i64*"]="Mem64Ref",
120 /*| ["i128*"]="Mem128Ref",["i256*"]="Mem256Ref",["i512*"]="Mem512Ref"}
121 /*| function insparms(op)
123 /*| for it,t in ipairs(op.operands) do
124 /*| if not t.fixed then
125 /*| parms = parms .. ", "..(t2t[t.type] or t.type).." "..op.orgnames[it]
130 /*| function relayparms(op)
132 /*| for it,t in ipairs(op.operands) do
133 /*| if not t.fixed then
134 /*| parms = parms .. ", "..op.orgnames[it]
139 /*| function consname(op)
140 /*| return "_ICons"..layoutlu2[op.opclass.layout.id].id
142 /*| function consparms(op)
144 /*| for it, v in ipairs(op.operands) do
145 /*| ren[v.name] = op.orgnames[it]
147 /*| local parms, l = "", layoutlu2[op.opclass.layout.id]
148 /*| for k,v in ipairs(l) do
149 /*| parms = parms .. ", "..(ren[v[2]])
153 /*| #define ADVANCE(IS,I) IS.advance(InsSizeCT<I>::Value)
154 /*| #define ALLOCINS(BB,I) bb->createTailIns(InsSizeCT<I>::Value)
155 /*| for k,op in pred_ipairs(data.ops, function(k,cl) return isa(op.opclass.isa) end) do
156 static inline void %(op.name)(InsRef ip%(insparms(op)))
157 { %(consname(op))(ip, I_%(op.name)%(consparms(op))); }
158 static inline void %(op.name)(InsStream &is%(insparms(op)))
159 { %(consname(op))(is.ip, I_%(op.name)%(consparms(op))); ADVANCE(is,I_%(op.name)); }
160 static inline void %(op.name)(BBlock* bb%(insparms(op)))
161 { %(consname(op))(ALLOCINS(bb,I_%(op.name)), I_%(op.name)%(consparms(op))); }
165 /*| local function grm(rm,n) return rm == "R" and ("GR"..n.."Ref") or ("Mem"..n.."Ref") end
166 /*| local ccs = {"O", "NO", "B", "AE", "E", "NE", "BE", "A", "S", "NS", "PE", "PO", "L", "GE", "LE", "G"}
167 /*| local oo, tname, oname, RM
168 /*| for rm_,RM_ in ipairs{"R","M"} do
169 /*| for k,v in pred_ipairs({{N=16,R="H"}, {N=32,R="W"}, {N=64, R="D",x64=true}},
170 /*| function(k,v) return v.N <= N end do
171 /*| RM = RM_ == "R" and v.R or "M"
172 /*| tname, oname = "CMOVCC_" .. v.R ..RM, "CMOVO_" .. v.R .. RM
173 /*| oo = opname2op[oname]
174 /*| for kk,vv in ipairs(ccs) do
175 jitcs_static_assert(I_%(oname) + CC_%(vv) == I_CMOV%(vv)_%(v.R)%(RM));
177 static inline void %(tname)(InsRef ip, CondCodeId cc%(insparms(oo))) {
178 %(consname(oo))(ip, static_cast<InsId>(I_%(oname)+cc)%(consparms(oo)));
180 static inline void %(tname)(InsStream& is, CondCodeId cc%(insparms(oo))) {
181 %(consname(oo))(is.ip, static_cast<InsId>(I_%(oname)+cc)%(consparms(oo))); ADVANCE(is,I_%(oname));
183 static inline void %(tname)(BBlock *bb, CondCodeId cc%(insparms(oo))) {
184 %(consname(oo))(ALLOCINS(bb,I_%(oname)), static_cast<InsId>(I_%(oname)+cc)%(consparms(oo)));
188 /*| RM = RM_ == "R" and "B" or "M8"
189 /*| tname, oname = "SETCC_" .. RM, "SETO_" .. RM
190 /*| oo = opname2op[oname]
191 /*| for kk,vv in ipairs(ccs) do
192 evm_static_assert(I_%(oname) + CC_%(vv) == I_SET%(vv)_%(RM));
194 static inline void %(tname)(InsRef ip, CondCodeId cc%(insparms(oo))) {
195 %(consname(oo))(ip, static_cast<InsId>(I_%(oname)+cc)%(consparms(oo)));
197 static inline void %(tname)(InsStream& is, CondCodeId cc%(insparms(oo))) {
198 %(consname(oo))(is.ip, static_cast<InsId>(I_%(oname)+cc)%(consparms(oo))); ADVANCE(is,I_%(oname));
200 static inline void %(tname)(BBlock *bb, CondCodeId cc%(insparms(oo))) {
201 %(consname(oo))(ALLOCINS(bb,I_%(oname)), static_cast<InsId>(I_%(oname)+cc)%(consparms(oo)));
205 /*| tname, oname = "JCC_BB_FT", "JO_BB_FT"
206 /*| oo = opname2op[oname]
207 /*| for kk,vv in ipairs(ccs) do
208 evm_static_assert(I_%(oname) + CC_%(vv) == I_J%(vv)_BB_FT);
210 static inline void %(tname)(InsRef ip, CondCodeId cc%(insparms(oo))) {
211 %(consname(oo))(ip, static_cast<InsId>(I_%(oname)+cc)%(consparms(oo)));
213 static inline void %(tname)(InsStream& is, CondCodeId cc%(insparms(oo))) {
214 %(consname(oo))(is.ip, static_cast<InsId>(I_%(oname)+cc)%(consparms(oo))); ADVANCE(is,I_%(oname));
216 static inline void %(tname)(BBlock *bb, CondCodeId cc%(insparms(oo))) {
217 %(consname(oo))(ALLOCINS(bb,I_%(oname)), static_cast<InsId>(I_%(oname)+cc)%(consparms(oo)));
220 /*| local al= runfile("../../../src-lib/x86/src/_x86_insalias.dat")
222 /*| local b = bar.start()
223 /*| for k,v in ipairs{{0,al.aliases}, {32,al.aliases32}, {64,al.aliases64}} do
224 /*| b = bar.continue2(b,v[1]==32,v[1]==64)
225 /*| for kk,vv in ipairs(v[2]) do
226 /*| tname, oname = vv[1], vv[2]
227 /*| oo = opname2op[oname]
228 static inline void %(tname)(InsRef ip%(insparms(oo))) {
229 %(consname(oo))(ip, I_%(oname)%(consparms(oo)));
231 static inline void %(tname)(InsStream& is%(insparms(oo))) {
232 %(consname(oo))(is.ip, I_%(oname)%(consparms(oo))); ADVANCE(is,I_%(oname));
234 static inline void %(tname)(BBlock *bb%(insparms(oo))) {
235 %(consname(oo))(ALLOCINS(bb,I_%(oname)), I_%(oname)%(consparms(oo)));
242 } // end of namespace jitcs::x86_%(N)
243 } // end of namespace jitcs
245 // _JITCS_X86_%(N)_CONS_H_