Initial commit
[jitcs.git] / include / tmp / jitcs_x86_xx_cons.lh
blob8b8c4ef619cb4024cb1412bc6c79e4d6c778a19f
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_memref.h"
31 #include "jitcs_bblock.h"
33 /*| local data= runfile("../src/data/x86_inslist.dat")
34 /*| --*/
36 namespace jitcs {
37 namespace x86_%(N) {
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];
44   }
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
51 /*|   end
52 /*|   local rsz = sz
53   template <> struct InsClassSizeCT<IC_%(cl.id)> { 
54     static const u8 Value = %rsz;
55   };
56 /*| end
57 /*| --*/
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
64 /*| end
65 /*| local opname2op = {}
66 /*| for k,v in ipairs(data.ops) do
67 /*|   opname2op[v.name] = v
68 /*| end
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 "")
75 /*|   end
76 /*|   if layoutlu[l.sig] then return layoutlu[l.sig] end
77 /*|   layoutlu[l.sig] = l
78 /*|   l.id = #layouts + 1
79 /*|   layouts[l.id] = l
80 /*|   return l
81 /*| end
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)
85 /*|   end
86 /*| end
87 /*| for id,l in ipairs(layouts) do
88 /*|   local parms = ""
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]
95 /*|     end
96 /*|   end
97 /*| --*/
98   //layout: %(l.sig)
99   inline void _ICons%(id)(InsRef ip, InsId id%(parms)) {
100     ip.setInsId(id);
101 /*|   for ix,t in ipairs(l) do
102 /*|     local value, fun = "", ""
103 /*|     value = t[2]
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
109 /*|     if value then
110     ip.set%(fun)Op(%ix, %(value));
111 /*|     end
112 /*|   end
113   }
114 /*| end
115 /*| --*/
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)
122 /*|   local parms=""
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]
126 /*|     end
127 /*|   end
128 /*|   return parms
129 /*| end
130 /*| function relayparms(op)
131 /*|   local parms=""
132 /*|   for it,t in ipairs(op.operands) do 
133 /*|     if not t.fixed then
134 /*|       parms = parms .. ", "..op.orgnames[it]
135 /*|     end
136 /*|   end
137 /*|   return parms
138 /*| end
139 /*| function consname(op)
140 /*|   return "_ICons"..layoutlu2[op.opclass.layout.id].id
141 /*| end
142 /*| function consparms(op)
143 /*|   local ren = {}
144 /*|   for it, v in ipairs(op.operands) do
145 /*|     ren[v.name] = op.orgnames[it]
146 /*|   end
147 /*|   local parms, l = "", layoutlu2[op.opclass.layout.id]
148 /*|   for k,v in ipairs(l) do
149 /*|     parms = parms .. ", "..(ren[v[2]])
150 /*|   end
151 /*|   return parms
152 /*| end
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))); }
162 /*| end
163 /*| --*/
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));
176 /*|     end
177   static inline void %(tname)(InsRef ip, CondCodeId cc%(insparms(oo))) { 
178     %(consname(oo))(ip, static_cast<InsId>(I_%(oname)+cc)%(consparms(oo))); 
179   }
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));
182   }
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)));
185   }
186 /*|   end
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));
193 /*|   end
194   static inline void %(tname)(InsRef ip, CondCodeId cc%(insparms(oo))) { 
195     %(consname(oo))(ip, static_cast<InsId>(I_%(oname)+cc)%(consparms(oo))); 
196   }
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));
199   }
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)));
202   }
203 /*| end
204 /*| --*/
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);
209 /*| end
210   static inline void %(tname)(InsRef ip, CondCodeId cc%(insparms(oo))) { 
211     %(consname(oo))(ip, static_cast<InsId>(I_%(oname)+cc)%(consparms(oo))); 
212   }
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));
215   }
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)));
218   }
220 /*| local al= runfile("../../../src-lib/x86/src/_x86_insalias.dat")
221   // here come aliases
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))); 
230   }
231   static inline void %(tname)(InsStream& is%(insparms(oo))) { 
232     %(consname(oo))(is.ip, I_%(oname)%(consparms(oo))); ADVANCE(is,I_%(oname));
233   }
234   static inline void %(tname)(BBlock *bb%(insparms(oo))) { 
235     %(consname(oo))(ALLOCINS(bb,I_%(oname)), I_%(oname)%(consparms(oo)));
236   }
237 /*|   end
238 /*| end
239 /*| #undef ADVANCE
240 /*| #undef ALLOCINS
242 } // end of namespace jitcs::x86_%(N)
243 } // end of namespace jitcs
244 #endif
245 // _JITCS_X86_%(N)_CONS_H_