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_instructionstream.h"
31 #include "jitcs_memref.h"
33 /*| local data= runfile("../src/data/x86_inslist.dat")
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
61 /*| local rsz = sz .. (i64 > 0 and (" + CI64Op * "..i64) or "")
62 template <> struct InsClass2SizeCT<ICL_%(cl.id)> { static const u8 Value = %rsz; };
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
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
76 /*| local opname2op = {}
77 /*| for k,v in ipairs(data.ops) do
78 /*| opname2op[v.name] = v
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
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 "")
91 /*| if layoutlu[l.sig] then return layoutlu[l.sig] end
92 /*| layoutlu[l.sig] = l
93 /*| l.id = #layouts + 1
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)
102 /*| for id,l in ipairs(layouts) do
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]
115 inline void _ICons%(id)(Ref<Instruction> ip, InsId id%(parms)) {
117 /*| for ix,t in ipairs(l) do
118 /*| local value, fun = "", ""
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))
128 ip->set%(fun)Op(%ix, %(value));
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)
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]
148 /*| function relayparms(op)
150 /*| for it,t in ipairs(op.operands) do
151 /*| if not t.fixed then
152 /*| parms = parms .. ", "..op.orgnames[it]
157 /*| function consname(op)
158 /*| return "_ICons"..layoutlu2[op.opclass.layout.id].id
160 /*| function consparms(op)
162 /*| for it, v in ipairs(op.operands) do
163 /*| ren[v.name] = op.orgnames[it]
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]])
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))); }
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");
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)));
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");
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)));
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");
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)));
216 /*| local al= runfile("../src/data/x86_insalias.dat")
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)));
228 } // end of namespace jitcs::x86_%(N)
229 } // end of namespace jitcs
231 // _JITCS_X86_%(N)_CONS_H_