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 isaN(k,v) return not v[N==32 and "x64" or "x32"] end
18 //===-- src/x86/jitcs_int_x86_%(N)_regs.h -------------------------*- C++ -*-===//
19 // X86, %(N)-bit, specific register information.
21 // Copyright (C) 2013-2014 Dirk Steinke.
22 // See copyright and license notice in COPYRIGHT or include/jitcs.h
23 //===----------------------------------------------------------------------===//
25 #ifndef _JITCS_INT_X86_%(N)_REGS_H_
26 #define _JITCS_INT_X86_%(N)_REGS_H_
29 #include "jitcs_ids.h"
30 #include "jitcs_x86_%(N)_regs.h"
32 /*| local data= runfile("../data/x86_reglist.dat")
33 /*| local function hex2(n) return string.format("0x%02x", n) end
40 /*| for k,v in ipairs(data.classes) do
43 /*| local c2r, c2ra, n2r = {}, {}, {}
44 /*| for k,v in ipairs(data.registers) do
46 /*| local c = c2r[v.class] or {}
50 /*| for k,v2 in ipairs(data.registeraliases) do
51 /*| local v = n2r[v2.dest]
52 /*| local c = c2ra[v.class] or {}
56 /*| resc2resid = {x32 = {}, sizex32 = {}, x32cnt = 0, x64 = {}, sizex64 = {}, x64cnt = 0}
57 /*| for k,v in ipairs(data.resources) do
59 /*| resc2resid.x32[v.name] = resc2resid.x32cnt;
60 /*| resc2resid.x32cnt = resc2resid.x32cnt + v.cnt
61 /*| resc2resid.sizex32[v.name] = v.cnt
64 /*| resc2resid.x64[v.name] = resc2resid.x64cnt;
65 /*| resc2resid.x64cnt = resc2resid.x64cnt + v.cnt
66 /*| resc2resid.sizex64[v.name] = v.cnt
69 /*| resc2rescid, rescidcnt, rescid2resc = {}, 0, {}
71 /*| for k,v in ipairs(data.classes) do
72 /*| regc2resc[v.name] = v.resclass
73 /*| if not resc2rescid[v.resclass] then
74 /*| resc2rescid[v.resclass] = rescidcnt
75 /*| rescid2resc[rescidcnt] = v.resclass
76 /*| rescidcnt = rescidcnt + 1
80 /*| for k,v in ipairs(data.resources) do
81 /*| if isaN(nil, v) then rescnt = rescnt + v.cnt end
84 static const ResId RES_Count = static_cast<ResId>(%(rescnt));
85 static const ResClassId RESCL_Count = static_cast<ResClassId>(%(rescidcnt));
87 /*| for k = 1, rescidcnt do
88 static const ResClassId RESCL_%(rescid2resc[k - 1]) = static_cast<ResClassId>(%(k - 1));
92 /*| local nn32, nn64, v2nn = 0, 0, {}
94 /*| for l,cl in ipairs(data.classes) do
95 /*| for k,v in ipairs(c2r[cl.name]) do
96 /*| local cond32 = (cl.x32 or not cl.x64) and (v.x32 or not v.x64)
97 /*| local cond64 = (not cl.x32 or cl.x64) and (not v.x32 or v.x64)
98 /*| if (z == 1 and cond32 and cond64) or (z == 2 and cond32 and not cond64) or (z == 3 and not cond32 and cond64) then
99 /*| v2nn[v.name] = {x32 = cond32 and nn32, x64 = cond64 and nn64}
100 /*| if (cond32) then nn32 = nn32 + 1 end
101 /*| if (cond64) then nn64 = nn64 + 1 end
108 template <uint N> struct RegInfoCT {};
109 template <uint N> struct ResInfoCT {};
110 template <uint N> struct RegClassInfoCT {};
111 template <uint N> struct ResClassInfoCT {};
113 /*| for k = 1, rescidcnt do
114 /*| local i = resc2resid["x"..N][rescid2resc[k - 1]]
115 /*| local v = resc2resid["sizex"..N][rescid2resc[k - 1]]
116 template<> struct ResClassInfoCT<RESCL_%(rescid2resc[k - 1])> {
117 enum { RES_Idx = %(i), RES_PoolSize = %(v) };
122 /*| reg2resid = {x32 = {}, x64 = {}}
123 /*| for k,v in ipairs(data.registers) do
124 /*| if not v.x64 then
125 /*| reg2resid.x32[v.name] = resc2resid.x32[regc2resc[v.class]] + v.resindex
127 /*| if not v.x32 then
128 /*| reg2resid.x64[v.name] = resc2resid.x64[regc2resc[v.class]] + v.resindex
131 /*| local function sum(rlist, subtype)
133 /*| for k,v in ipairs(rlist) do
134 /*| s = s + math.pow(2, reg2resid[subtype][v])
136 /*| return string.format("0x%x", s)
138 /*| local res2rescl = {}
139 /*| for k,v in pred_ipairs(data.registers, isaN) do
140 /*| local vv = reg2resid["x"..N][v.name]
142 /*| if not res2rescl[vv] then
143 /*| res2rescl[vv] = { ["x"..N] = regc2resc[v.class] }
145 /*| assert(not res2rescl[vv]["x"..N] or res2rescl[vv]["x"..N] == regc2resc[v.class])
146 /*| res2rescl[vv]["x"..N] = regc2resc[v.class]
149 template <> struct RegInfoCT<R_%(v.name)> {
150 static const ResId RES_Id = static_cast<ResId>(%(vv));
151 static const ResClassId RESCL_Id = RESCL_%(regc2resc[v.class]);
152 static const RegClassId RCL_Id = RCL_%(v.refclass or "Count");
153 static const uint VR_Idx = %(v2nn[v.name]["x"..N]);
154 typedef RegLookup<_fixedRegister%(v2nn[v.name]["x"..N]), RSC_%(v.class)> RegAccessorType;
157 /*| for k = 1, rescnt do
158 /*| local vv = res2rescl[k-1]["x"..N]
159 template <> struct ResInfoCT<%(k-1)> {
160 static const ResClassId RESCL_Id = RESCL_%(vv);
164 /*| local LogTable = {[0] = 0, [1] = 0, [2] = 1, [4] = 2, [8] = 3, [16] = 4, [32] = 5, [64] = 6}
165 /*| for l,cl in pred_ipairs(data.refclasses, isaN) do
167 /*| if cl.dontalloc then
168 /*| local f,t = cl.dontalloc:match("^(%d+)%-(%d+)$")
169 /*| if f and t then da = 2 ^ (t+1) - 2 ^ f end
171 template <> struct RegClassInfoCT<RCL_%(cl.name)> {
172 static const ResClassId RESCL_Id = RESCL_%(regc2resc[cl.classes[1]]);
173 static const u16 MASK_DontAlloc = %(da);
174 static const u8 SIZE = %(cl.defsz);
175 static const u8 LOGSIZE = %(LogTable[cl.defsz]);
180 /*| local minid, maxid = 255, 0
181 /*| for k,v in pred_ipairs(data.registers, isaN) do
182 /*| if v.id > maxid then maxid = v.id end
183 /*| if v.id < minid then minid = v.id end
185 extern const u8 ArrayReg2RegClass[%(maxid-minid+1)];
186 extern const u8 ArrayReg2Res[%(maxid-minid+1)];
187 extern const u8 ArrayRegClass2ResClass[RCL_Count];
188 extern const u8 ArrayRegClass2LogSize[RCL_Count];
189 extern const u16 ArrayRegClass2DontAlloc[RCL_Count];
190 extern const u8 ArrayRes2ResClass[RES_Count];
191 extern const u8 ArrayResClass2ResClassIndex[RESCL_Count];
192 extern const u8 ArrayResClass2ResClassSize[RESCL_Count];
193 static inline RegClassId GetRegClassOfReg(RegId r) {
194 assert(r >= %(minid) && r <= %(maxid));
195 return static_cast<RegClassId>(ArrayReg2RegClass[r-%(minid)]);
197 static inline ResId GetResOfReg(RegId r) {
198 if (r >= R_HardwareLimit) return static_cast<ResId>(RES_Count + r - R_HardwareLimit);
199 assert(r >= %(minid) && r <= %(maxid));
200 return static_cast<ResId>(ArrayReg2Res[r-%(minid)]);
202 static inline ResClassId GetResClassOfRegClass(RegClassId rc) {
203 assert(rc < RCL_Count);
204 return static_cast<ResClassId>(ArrayRegClass2ResClass[rc]);
206 static inline ResClassId GetResClassOfReg(RegId r) {
207 return GetResClassOfRegClass(GetRegClassOfReg(r));
209 static inline u8 GetLogSizeOfRegClass(RegClassId rc) {
210 assert(rc < RCL_Count);
211 return ArrayRegClass2LogSize[rc];
213 static inline u16 GetDontAllocOfRegClass(RegClassId rc) {
214 assert(rc < RCL_Count);
215 return ArrayRegClass2DontAlloc[rc];
217 static inline ResClassId GetResClassOfRes(ResId res) {
218 assert(res < RES_Count);
219 return static_cast<ResClassId>(ArrayRes2ResClass[res]);
221 static inline u8 GetResIndexOfResClass(ResClassId rescl) {
222 assert(rescl < RESCL_Count);
223 return ArrayResClass2ResClassIndex[rescl];
225 static inline u8 GetSizeOfResClass(ResClassId rescl) {
226 assert(rescl < RESCL_Count);
227 return ArrayResClass2ResClassSize[rescl];
229 RegId GetRegIdForRes(RegClassId rc, ResId res);
230 //RefOrNull<const VirtualRegister>
231 // GetHardwareRegisterForRes(RegClassId rc, ResId res);
233 } // end of namespace jitcs::x86_%(N)
234 } // end of namespace jitcs
236 // _JITCS_INT_X86_%(N)_REGS_H_