History

match jumps/ops with il text

Quentin Carbonneaux committed 10 years ago

Commit 657c3fa1 parent b7debc411 files · +509 −509Browse files

Unified · Split

11 files
  1. all.h +88 −88
  2. copy.c +2 −2
  3. emit.c +80 −80
  4. fold.c +53 −53
  5. isel.c +83 −83
  6. live.c +1 −1
  7. mem.c +17 −17
  8. parse.c +114 −114
  9. rega.c +10 −10
  10. spill.c +5 −5
  11. sysv.c +56 −56
all.h+88−88
@@ -162,8 +162,8 @@ enum ICmp { · 161 unmodified lines
162#undef X162#undef X
163 NICmp,163 NICmp,
164 164
165 ICXnp = NICmp, /* x64 specific */165 ICxnp = NICmp, /* x64 specific */
166 ICXp,166 ICxp,
167 NXICmp167 NXICmp
168};168};
169 169
@@ -201,103 +201,103 @@ enum Class { · 31 unmodified lines
201#define KBASE(k) ((k)>>1)201#define KBASE(k) ((k)>>1)
202 202
203enum Op {203enum Op {
204 OXXX,204 Oxxx,
205 205
206 /* public instructions */206 /* public instructions */
207 OAdd,207 Oadd,
208 OSub,208 Osub,
209 ODiv,209 Odiv,
210 ORem,210 Orem,
211 OUDiv,211 Oudiv,
212 OURem,212 Ourem,
213 OMul,213 Omul,
214 OAnd,214 Oand,
215 OOr,215 Oor,
216 OXor,216 Oxor,
217 OSar,217 Osar,
218 OShr,218 Oshr,
219 OShl,219 Oshl,
220 OCmpw,220 Ocmpw,
221 OCmpw1 = OCmpw + NICmp-1,221 Ocmpw1 = Ocmpw + NICmp-1,
222 OCmpl,222 Ocmpl,
223 OCmpl1 = OCmpl + NICmp-1,223 Ocmpl1 = Ocmpl + NICmp-1,
224 OCmps,224 Ocmps,
225 OCmps1 = OCmps + NFCmp-1,225 Ocmps1 = Ocmps + NFCmp-1,
226 OCmpd,226 Ocmpd,
227 OCmpd1 = OCmpd + NFCmp-1,227 Ocmpd1 = Ocmpd + NFCmp-1,
228 228
229 OStoreb,229 Ostoreb,
230 OStoreh,230 Ostoreh,
231 OStorew,231 Ostorew,
232 OStorel,232 Ostorel,
233 OStores,233 Ostores,
234 OStored,234 Ostored,
235#define isstore(o) (OStoreb <= o && o <= OStored)235#define isstore(o) (Ostoreb <= o && o <= Ostored)
236 OLoadsb, /* needs to match OExt (mem.c) */236 Oloadsb, /* needs to match OExt (mem.c) */
237 OLoadub,237 Oloadub,
238 OLoadsh,238 Oloadsh,
239 OLoaduh,239 Oloaduh,
240 OLoadsw,240 Oloadsw,
241 OLoaduw,241 Oloaduw,
242 OLoad,242 Oload,
243#define isload(o) (OLoadsb <= o && o <= OLoad)243#define isload(o) (Oloadsb <= o && o <= Oload)
244 OExtsb,244 Oextsb,
245 OExtub,245 Oextub,
246 OExtsh,246 Oextsh,
247 OExtuh,247 Oextuh,
248 OExtsw,248 Oextsw,
249 OExtuw,249 Oextuw,
250#define isext(o) (OExtsb <= o && o <= OExtuw)250#define isext(o) (Oextsb <= o && o <= Oextuw)
251 251
252 OExts,252 Oexts,
253 OTruncd,253 Otruncd,
254 OFtosi,254 Oftosi,
255 OSitof,255 Ositof,
256 OCast,256 Ocast,
257 257
258 OAlloc,258 Oalloc,
259 OAlloc1 = OAlloc + NAlign-1,259 Oalloc1 = Oalloc + NAlign-1,
260 260
261 OCopy,261 Ocopy,
262 NPubOp,262 NPubOp,
263 263
264 /* function instructions */264 /* function instructions */
265 OPar = NPubOp,265 Opar = NPubOp,
266 OParc,266 Oparc,
267 OArg,267 Oarg,
268 OArgc,268 Oargc,
269 OCall,269 Ocall,
270 270
271 /* reserved instructions */271 /* reserved instructions */
272 ONop,272 Onop,
273 OAddr,273 Oaddr,
274 OSwap,274 Oswap,
275 OSign,275 Osign,
276 OSAlloc,276 Osalloc,
277 OXIDiv,277 Oxidiv,
278 OXDiv,278 Oxdiv,
279 OXCmp,279 Oxcmp,
280 OXSet,280 Oxset,
281 OXSetnp = OXSet + ICXnp,281 Oxsetnp = Oxset + ICxnp,
282 OXSetp = OXSet + ICXp,282 Oxsetp = Oxset + ICxp,
283 OXTest,283 Oxtest,
284 NOp284 NOp
285};285};
286 286
287enum Jmp {287enum Jmp {
288 JXXX,288 Jxxx,
289 JRet0,289 Jret0,
290 JRetw,290 Jretw,
291 JRetl,291 Jretl,
292 JRets,292 Jrets,
293 JRetd,293 Jretd,
294 JRetc,294 Jretc,
295#define isret(j) (JRet0 <= j && j <= JRetc)295#define isret(j) (Jret0 <= j && j <= Jretc)
296 JJmp,296 Jjmp,
297 JJnz,297 Jjnz,
298 JXJc,298 Jxjc,
299 JXJnp = JXJc + ICXnp,299 Jxjnp = Jxjc + ICxnp,
300 JXJp = JXJc + ICXp,300 Jxjp = Jxjc + ICxp,
301 NJmp301 NJmp
302};302};
303 303
copy.c+2−2
@@ -55,7 +55,7 @@ visitins(Ins *i, Ref *cp, RList **w) · 54 unmodified lines
55{55{
56 Ref r;56 Ref r;
57 57
58 if (i->op == OCopy) {58 if (i->op == Ocopy) {
59 r = copyof(i->arg[0], cp);59 r = copyof(i->arg[0], cp);
60 update(i->to, r, cp, w);60 update(i->to, r, cp, w);
61 } else if (!req(i->to, R)) {61 } else if (!req(i->to, R)) {
@@ -125,7 +125,7 @@ copy(Fn *fn) · 63 unmodified lines
125 for (i=b->ins; i-b->ins < b->nins; i++) {125 for (i=b->ins; i-b->ins < b->nins; i++) {
126 r = copyof(i->to, cp);126 r = copyof(i->to, cp);
127 if (!req(r, i->to)) {127 if (!req(r, i->to)) {
128 *i = (Ins){.op = ONop};128 *i = (Ins){.op = Onop};
129 continue;129 continue;
130 }130 }
131 for (a=0; a<2; a++)131 for (a=0; a<2; a++)
emit.c+80−80
@@ -43,70 +43,70 @@ static struct { · 42 unmodified lines
43 short cls;43 short cls;
44 char *asm;44 char *asm;
45} omap[] = {45} omap[] = {
46 { OAdd, Ka, "+add%k %1, %=" },46 { Oadd, Ka, "+add%k %1, %=" },
47 { OSub, Ka, "-sub%k %1, %=" },47 { Osub, Ka, "-sub%k %1, %=" },
48 { OAnd, Ki, "+and%k %1, %=" },48 { Oand, Ki, "+and%k %1, %=" },
49 { OOr, Ki, "+or%k %1, %=" },49 { Oor, Ki, "+or%k %1, %=" },
50 { OXor, Ki, "+xor%k %1, %=" },50 { Oxor, Ki, "+xor%k %1, %=" },
51 { OSar, Ki, "-sar%k %B1, %=" },51 { Osar, Ki, "-sar%k %B1, %=" },
52 { OShr, Ki, "-shr%k %B1, %=" },52 { Oshr, Ki, "-shr%k %B1, %=" },
53 { OShl, Ki, "-shl%k %B1, %=" },53 { Oshl, Ki, "-shl%k %B1, %=" },
54 { OMul, Ki, "+imul%k %1, %=" },54 { Omul, Ki, "+imul%k %1, %=" },
55 { OMul, Ks, "+mulss %1, %=" }, /* fixme */55 { Omul, Ks, "+mulss %1, %=" }, /* fixme */
56 { OMul, Kd, "+mulsd %1, %=" },56 { Omul, Kd, "+mulsd %1, %=" },
57 { ODiv, Ka, "-div%k %1, %=" },57 { Odiv, Ka, "-div%k %1, %=" },
58 { OStorel, Ka, "movq %L0, %M1" },58 { Ostorel, Ka, "movq %L0, %M1" },
59 { OStorew, Ka, "movl %W0, %M1" },59 { Ostorew, Ka, "movl %W0, %M1" },
60 { OStoreh, Ka, "movw %H0, %M1" },60 { Ostoreh, Ka, "movw %H0, %M1" },
61 { OStoreb, Ka, "movb %B0, %M1" },61 { Ostoreb, Ka, "movb %B0, %M1" },
62 { OStores, Ka, "movss %S0, %M1" },62 { Ostores, Ka, "movss %S0, %M1" },
63 { OStored, Ka, "movsd %D0, %M1" },63 { Ostored, Ka, "movsd %D0, %M1" },
64 { OLoad, Ka, "mov%k %M0, %=" },64 { Oload, Ka, "mov%k %M0, %=" },
65 { OLoadsw, Kl, "movslq %M0, %L=" },65 { Oloadsw, Kl, "movslq %M0, %L=" },
66 { OLoadsw, Kw, "movl %M0, %W=" },66 { Oloadsw, Kw, "movl %M0, %W=" },
67 { OLoaduw, Ki, "movl %M0, %W=" },67 { Oloaduw, Ki, "movl %M0, %W=" },
68 { OLoadsh, Ki, "movsw%k %M0, %=" },68 { Oloadsh, Ki, "movsw%k %M0, %=" },
69 { OLoaduh, Ki, "movzw%k %M0, %=" },69 { Oloaduh, Ki, "movzw%k %M0, %=" },
70 { OLoadsb, Ki, "movsb%k %M0, %=" },70 { Oloadsb, Ki, "movsb%k %M0, %=" },
71 { OLoadub, Ki, "movzb%k %M0, %=" },71 { Oloadub, Ki, "movzb%k %M0, %=" },
72 { OExtsw, Kl, "movslq %W0, %L=" },72 { Oextsw, Kl, "movslq %W0, %L=" },
73 { OExtuw, Kl, "movl %W0, %W=" },73 { Oextuw, Kl, "movl %W0, %W=" },
74 { OExtsh, Ki, "movsw%k %H0, %=" },74 { Oextsh, Ki, "movsw%k %H0, %=" },
75 { OExtuh, Ki, "movzw%k %H0, %=" },75 { Oextuh, Ki, "movzw%k %H0, %=" },
76 { OExtsb, Ki, "movsb%k %B0, %=" },76 { Oextsb, Ki, "movsb%k %B0, %=" },
77 { OExtub, Ki, "movzb%k %B0, %=" },77 { Oextub, Ki, "movzb%k %B0, %=" },
78 78
79 { OExts, Kd, "cvtss2sd %0, %=" }, /* see if factorization is possible */79 { Oexts, Kd, "cvtss2sd %0, %=" }, /* see if factorization is possible */
80 { OTruncd, Ks, "cvttsd2ss %0, %=" },80 { Otruncd, Ks, "cvttsd2ss %0, %=" },
81 { OFtosi, Kw, "cvttss2si %0, %=" },81 { Oftosi, Kw, "cvttss2si %0, %=" },
82 { OFtosi, Kl, "cvttsd2si %0, %=" },82 { Oftosi, Kl, "cvttsd2si %0, %=" },
83 { OSitof, Ks, "cvtsi2ss %W0, %=" },83 { Ositof, Ks, "cvtsi2ss %W0, %=" },
84 { OSitof, Kd, "cvtsi2sd %L0, %=" },84 { Ositof, Kd, "cvtsi2sd %L0, %=" },
85 { OCast, Ki, "movq %D0, %L=" },85 { Ocast, Ki, "movq %D0, %L=" },
86 { OCast, Ka, "movq %L0, %D=" },86 { Ocast, Ka, "movq %L0, %D=" },
87 87
88 { OAddr, Ki, "lea%k %M0, %=" },88 { Oaddr, Ki, "lea%k %M0, %=" },
89 { OSwap, Ki, "xchg%k %0, %1" },89 { Oswap, Ki, "xchg%k %0, %1" },
90 { OSign, Kl, "cqto" },90 { Osign, Kl, "cqto" },
91 { OSign, Kw, "cltd" },91 { Osign, Kw, "cltd" },
92 { OXDiv, Ki, "div%k %0" },92 { Oxdiv, Ki, "div%k %0" },
93 { OXIDiv, Ki, "idiv%k %0" },93 { Oxidiv, Ki, "idiv%k %0" },
94 { OXCmp, Ks, "comiss %S0, %S1" }, /* fixme, Kf */94 { Oxcmp, Ks, "comiss %S0, %S1" }, /* fixme, Kf */
95 { OXCmp, Kd, "comisd %D0, %D1" },95 { Oxcmp, Kd, "comisd %D0, %D1" },
96 { OXCmp, Ki, "cmp%k %0, %1" },96 { Oxcmp, Ki, "cmp%k %0, %1" },
97 { OXTest, Ki, "test%k %0, %1" },97 { Oxtest, Ki, "test%k %0, %1" },
98 { OXSet+ICule, Ki, "setbe %B=\n\tmovzb%k %B=, %=" },98 { Oxset+ICule, Ki, "setbe %B=\n\tmovzb%k %B=, %=" },
99 { OXSet+ICult, Ki, "setb %B=\n\tmovzb%k %B=, %=" },99 { Oxset+ICult, Ki, "setb %B=\n\tmovzb%k %B=, %=" },
100 { OXSet+ICsle, Ki, "setle %B=\n\tmovzb%k %B=, %=" },100 { Oxset+ICsle, Ki, "setle %B=\n\tmovzb%k %B=, %=" },
101 { OXSet+ICslt, Ki, "setl %B=\n\tmovzb%k %B=, %=" },101 { Oxset+ICslt, Ki, "setl %B=\n\tmovzb%k %B=, %=" },
102 { OXSet+ICsgt, Ki, "setg %B=\n\tmovzb%k %B=, %=" },102 { Oxset+ICsgt, Ki, "setg %B=\n\tmovzb%k %B=, %=" },
103 { OXSet+ICsge, Ki, "setge %B=\n\tmovzb%k %B=, %=" },103 { Oxset+ICsge, Ki, "setge %B=\n\tmovzb%k %B=, %=" },
104 { OXSet+ICugt, Ki, "seta %B=\n\tmovzb%k %B=, %=" },104 { Oxset+ICugt, Ki, "seta %B=\n\tmovzb%k %B=, %=" },
105 { OXSet+ICuge, Ki, "setae %B=\n\tmovzb%k %B=, %=" },105 { Oxset+ICuge, Ki, "setae %B=\n\tmovzb%k %B=, %=" },
106 { OXSet+ICeq, Ki, "setz %B=\n\tmovzb%k %B=, %=" },106 { Oxset+ICeq, Ki, "setz %B=\n\tmovzb%k %B=, %=" },
107 { OXSet+ICne, Ki, "setnz %B=\n\tmovzb%k %B=, %=" },107 { Oxset+ICne, Ki, "setnz %B=\n\tmovzb%k %B=, %=" },
108 { OXSet+ICXnp, Ki, "setnp %B=\n\tmovsb%k %B=, %=" },108 { Oxset+ICxnp, Ki, "setnp %B=\n\tmovsb%k %B=, %=" },
109 { OXSet+ICXp, Ki, "setp %B=\n\tmovsb%k %B=, %=" },109 { Oxset+ICxp, Ki, "setp %B=\n\tmovsb%k %B=, %=" },
110 { NOp, 0, 0 }110 { NOp, 0, 0 }
111};111};
112 112
@@ -200,7 +200,7 @@ emitcopy(Ref r1, Ref r2, int k, Fn *fn, FILE *f) · 87 unmodified lines
200{200{
201 Ins icp;201 Ins icp;
202 202
203 icp.op = OCopy;203 icp.op = Ocopy;
204 icp.arg[0] = r2;204 icp.arg[0] = r2;
205 icp.to = r1;205 icp.to = r1;
206 icp.cls = k;206 icp.cls = k;
@@ -364,11 +364,11 @@ emitins(Ins i, Fn *fn, FILE *f) · 157 unmodified lines
364 }364 }
365 emitf(omap[o].asm, &i, fn, f);365 emitf(omap[o].asm, &i, fn, f);
366 break;366 break;
367 case ONop:367 case Onop:
368 /* just do nothing for nops, they are inserted368 /* just do nothing for nops, they are inserted
369 * by some passes */369 * by some passes */
370 break;370 break;
371 case OMul:371 case Omul:
372 /* here, we try to use the 3-addresss form372 /* here, we try to use the 3-addresss form
373 * of multiplication when possible */373 * of multiplication when possible */
374 if (rtype(i.arg[1]) == RCon) {374 if (rtype(i.arg[1]) == RCon) {
@@ -383,7 +383,7 @@ emitins(Ins i, Fn *fn, FILE *f) · 8 unmodified lines
383 break;383 break;
384 }384 }
385 goto Table;385 goto Table;
386 case OSub:386 case Osub:
387 /* we have to use the negation trick to handle387 /* we have to use the negation trick to handle
388 * some 3-address substractions */388 * some 3-address substractions */
389 if (req(i.to, i.arg[1])) {389 if (req(i.to, i.arg[1])) {
@@ -392,7 +392,7 @@ emitins(Ins i, Fn *fn, FILE *f) · 2 unmodified lines
392 break;392 break;
393 }393 }
394 goto Table;394 goto Table;
395 case OCopy:395 case Ocopy:
396 /* make sure we don't emit useless copies,396 /* make sure we don't emit useless copies,
397 * also, we can use a trick to load 64-bits397 * also, we can use a trick to load 64-bits
398 * registers, it's detailed in my note below398 * registers, it's detailed in my note below
@@ -413,7 +413,7 @@ emitins(Ins i, Fn *fn, FILE *f) · 14 unmodified lines
413 } else if (!req(i.arg[0], i.to))413 } else if (!req(i.arg[0], i.to))
414 emitf("mov%k %0, %=", &i, fn, f);414 emitf("mov%k %0, %=", &i, fn, f);
415 break;415 break;
416 case OCall:416 case Ocall:
417 /* calls simply have a weird syntax in AT&T417 /* calls simply have a weird syntax in AT&T
418 * assembly... */418 * assembly... */
419 switch (rtype(i.arg[0])) {419 switch (rtype(i.arg[0])) {
@@ -429,16 +429,16 @@ emitins(Ins i, Fn *fn, FILE *f) · 9 unmodified lines
429 die("invalid call argument");429 die("invalid call argument");
430 }430 }
431 break;431 break;
432 case OSAlloc:432 case Osalloc:
433 /* there is no good reason why this is here433 /* there is no good reason why this is here
434 * maybe we should split OSAlloc in 2 different434 * maybe we should split Osalloc in 2 different
435 * instructions depending on the result435 * instructions depending on the result
436 */436 */
437 emitf("subq %L0, %%rsp", &i, fn, f);437 emitf("subq %L0, %%rsp", &i, fn, f);
438 if (!req(i.to, R))438 if (!req(i.to, R))
439 emitcopy(i.to, TMP(RSP), Kl, fn, f);439 emitcopy(i.to, TMP(RSP), Kl, fn, f);
440 break;440 break;
441 case OSwap:441 case Oswap:
442 if (KBASE(i.cls) == 0)442 if (KBASE(i.cls) == 0)
443 goto Table;443 goto Table;
444 /* for floats, there is no swap instruction444 /* for floats, there is no swap instruction
@@ -466,8 +466,8 @@ cneg(int cmp) · 21 unmodified lines
466 case ICuge: return ICult;466 case ICuge: return ICult;
467 case ICeq: return ICne;467 case ICeq: return ICne;
468 case ICne: return ICeq;468 case ICne: return ICeq;
469 case ICXnp: return ICXp;469 case ICxnp: return ICxp;
470 case ICXp: return ICXnp;470 case ICxp: return ICxnp;
471 }471 }
472}472}
473 473
@@ -498,8 +498,8 @@ emitfn(Fn *fn, FILE *f) · 24 unmodified lines
498 [ICugt] = "a",498 [ICugt] = "a",
499 [ICuge] = "ae",499 [ICuge] = "ae",
500 [ICne] = "nz",500 [ICne] = "nz",
501 [ICXnp] = "np",501 [ICxnp] = "np",
502 [ICXp] = "p"502 [ICxp] = "p"
503 };503 };
504 static int id0;504 static int id0;
505 Blk *b, *s;505 Blk *b, *s;
@@ -529,7 +529,7 @@ emitfn(Fn *fn, FILE *f) · 23 unmodified lines
529 for (i=b->ins; i!=&b->ins[b->nins]; i++)529 for (i=b->ins; i!=&b->ins[b->nins]; i++)
530 emitins(*i, fn, f);530 emitins(*i, fn, f);
531 switch (b->jmp.type) {531 switch (b->jmp.type) {
532 case JRet0:532 case Jret0:
533 for (r=&rclob[NRClob]; r>rclob;)533 for (r=&rclob[NRClob]; r>rclob;)
534 if (fn->reg & BIT(*--r)) {534 if (fn->reg & BIT(*--r)) {
535 itmp.arg[0] = TMP(*r);535 itmp.arg[0] = TMP(*r);
@@ -540,14 +540,14 @@ emitfn(Fn *fn, FILE *f) · 4 unmodified lines
540 "\tret\n"540 "\tret\n"
541 );541 );
542 break;542 break;
543 case JJmp:543 case Jjmp:
544 Jmp:544 Jmp:
545 if (b->s1 != b->link)545 if (b->s1 != b->link)
546 fprintf(f, "\tjmp %sbb%d /* %s */\n",546 fprintf(f, "\tjmp %sbb%d /* %s */\n",
547 locprefix, id0+b->s1->id, b->s1->name);547 locprefix, id0+b->s1->id, b->s1->name);
548 break;548 break;
549 default:549 default:
550 c = b->jmp.type - JXJc;550 c = b->jmp.type - Jxjc;
551 if (0 <= c && c <= NXICmp) {551 if (0 <= c && c <= NXICmp) {
552 if (b->link == b->s2) {552 if (b->link == b->s2) {
553 s = b->s1;553 s = b->s1;
fold.c+53−53
@@ -124,7 +124,7 @@ visitjmp(Blk *b, int n, Fn *fn) · 123 unmodified lines
124 int l;124 int l;
125 125
126 switch (b->jmp.type) {126 switch (b->jmp.type) {
127 case JJnz:127 case Jjnz:
128 l = latval(b->jmp.arg);128 l = latval(b->jmp.arg);
129 assert(l != Top && "ssa invariant broken");129 assert(l != Top && "ssa invariant broken");
130 if (l == Bot) {130 if (l == Bot) {
@@ -143,7 +143,7 @@ visitjmp(Blk *b, int n, Fn *fn) · 12 unmodified lines
143 flowrk = &edge[n][0];143 flowrk = &edge[n][0];
144 }144 }
145 break;145 break;
146 case JJmp:146 case Jjmp:
147 edge[n][0].work = flowrk;147 edge[n][0].work = flowrk;
148 flowrk = &edge[n][0];148 flowrk = &edge[n][0];
149 break;149 break;
@@ -226,7 +226,7 @@ fold(Fn *fn) · 76 unmodified lines
226 visitjmp(b, n, fn);226 visitjmp(b, n, fn);
227 }227 }
228 b->visit++;228 b->visit++;
229 assert(b->jmp.type != JJmp229 assert(b->jmp.type != Jjmp
230 || !edge[n][0].dead230 || !edge[n][0].dead
231 || flowrk == &edge[n][0]);231 || flowrk == &edge[n][0]);
232 }232 }
@@ -290,13 +290,13 @@ fold(Fn *fn) · 57 unmodified lines
290 }290 }
291 for (i=b->ins; i-b->ins < b->nins; i++)291 for (i=b->ins; i-b->ins < b->nins; i++)
292 if (renref(&i->to))292 if (renref(&i->to))
293 *i = (Ins){.op = ONop};293 *i = (Ins){.op = Onop};
294 else294 else
295 for (n=0; n<2; n++)295 for (n=0; n<2; n++)
296 renref(&i->arg[n]);296 renref(&i->arg[n]);
297 renref(&b->jmp.arg);297 renref(&b->jmp.arg);
298 if (b->jmp.type == JJnz && rtype(b->jmp.arg) == RCon) {298 if (b->jmp.type == Jjnz && rtype(b->jmp.arg) == RCon) {
299 b->jmp.type = JJmp;299 b->jmp.type = Jjmp;
300 if (czero(&fn->con[b->jmp.arg.val], 0))300 if (czero(&fn->con[b->jmp.arg.val], 0))
301 b->s1 = b->s2;301 b->s1 = b->s2;
302 b->jmp.arg = R;302 b->jmp.arg = R;
@@ -333,7 +333,7 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 30 unmodified lines
333 lab = 0;333 lab = 0;
334 l.s = cl->bits.i;334 l.s = cl->bits.i;
335 r.s = cr->bits.i;335 r.s = cr->bits.i;
336 if (op == OAdd) {336 if (op == Oadd) {
337 if (cl->type == CAddr) {337 if (cl->type == CAddr) {
338 if (cr->type == CAddr)338 if (cr->type == CAddr)
339 err("undefined addition (addr + addr)");339 err("undefined addition (addr + addr)");
@@ -342,7 +342,7 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 2 unmodified lines
342 else if (cr->type == CAddr)342 else if (cr->type == CAddr)
343 lab = cr->label;343 lab = cr->label;
344 }344 }
345 else if (op == OSub) {345 else if (op == Osub) {
346 if (cl->type == CAddr) {346 if (cl->type == CAddr) {
347 if (cr->type != CAddr)347 if (cr->type != CAddr)
348 lab = cl->label;348 lab = cl->label;
@@ -355,44 +355,44 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 6 unmodified lines
355 else if (cl->type == CAddr || cr->type == CAddr)355 else if (cl->type == CAddr || cr->type == CAddr)
356 err("invalid address operand for '%s'", opdesc[op].name);356 err("invalid address operand for '%s'", opdesc[op].name);
357 switch (op) {357 switch (op) {
358 case OAdd: x = l.u + r.u; break;358 case Oadd: x = l.u + r.u; break;
359 case OSub: x = l.u - r.u; break;359 case Osub: x = l.u - r.u; break;
360 case ODiv: x = l.s / r.s; break;360 case Odiv: x = l.s / r.s; break;
361 case ORem: x = l.s % r.s; break;361 case Orem: x = l.s % r.s; break;
362 case OUDiv: x = l.u / r.u; break;362 case Oudiv: x = l.u / r.u; break;
363 case OURem: x = l.u % r.u; break;363 case Ourem: x = l.u % r.u; break;
364 case OMul: x = l.u * r.u; break;364 case Omul: x = l.u * r.u; break;
365 case OAnd: x = l.u & r.u; break;365 case Oand: x = l.u & r.u; break;
366 case OOr: x = l.u | r.u; break;366 case Oor: x = l.u | r.u; break;
367 case OXor: x = l.u ^ r.u; break;367 case Oxor: x = l.u ^ r.u; break;
368 case OSar: x = l.s >> (r.u & 63); break;368 case Osar: x = l.s >> (r.u & 63); break;
369 case OShr: x = l.u >> (r.u & 63); break;369 case Oshr: x = l.u >> (r.u & 63); break;
370 case OShl: x = l.u << (r.u & 63); break;370 case Oshl: x = l.u << (r.u & 63); break;
371 case OExtsb: x = (int8_t)l.u; break;371 case Oextsb: x = (int8_t)l.u; break;
372 case OExtub: x = (uint8_t)l.u; break;372 case Oextub: x = (uint8_t)l.u; break;
373 case OExtsh: x = (int16_t)l.u; break;373 case Oextsh: x = (int16_t)l.u; break;
374 case OExtuh: x = (uint16_t)l.u; break;374 case Oextuh: x = (uint16_t)l.u; break;
375 case OExtsw: x = (int32_t)l.u; break;375 case Oextsw: x = (int32_t)l.u; break;
376 case OExtuw: x = (uint32_t)l.u; break;376 case Oextuw: x = (uint32_t)l.u; break;
377 case OFtosi:377 case Oftosi:
378 if (w)378 if (w)
379 x = (int64_t)cl->bits.d;379 x = (int64_t)cl->bits.d;
380 else380 else
381 x = (int32_t)cl->bits.s;381 x = (int32_t)cl->bits.s;
382 break;382 break;
383 case OCast:383 case Ocast:
384 x = l.u;384 x = l.u;
385 if (cl->type == CAddr)385 if (cl->type == CAddr)
386 lab = cl->label;386 lab = cl->label;
387 break;387 break;
388 default:388 default:
389 if (OCmpw <= op && op <= OCmpl1) {389 if (Ocmpw <= op && op <= Ocmpl1) {
390 if (op <= OCmpw1) {390 if (op <= Ocmpw1) {
391 l.u = (uint32_t)l.u;391 l.u = (uint32_t)l.u;
392 r.u = (uint32_t)r.u;392 r.u = (uint32_t)r.u;
393 } else393 } else
394 op -= OCmpl - OCmpw;394 op -= Ocmpl - Ocmpw;
395 switch (op - OCmpw) {395 switch (op - Ocmpw) {
396 case ICule: x = l.u <= r.u; break;396 case ICule: x = l.u <= r.u; break;
397 case ICult: x = l.u < r.u; break;397 case ICult: x = l.u < r.u; break;
398 case ICsle: x = l.s <= r.s; break;398 case ICsle: x = l.s <= r.s; break;
@@ -406,8 +406,8 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 7 unmodified lines
406 default: die("unreachable");406 default: die("unreachable");
407 }407 }
408 }408 }
409 else if (OCmps <= op && op <= OCmps1) {409 else if (Ocmps <= op && op <= Ocmps1) {
410 switch (op - OCmps) {410 switch (op - Ocmps) {
411 case FCle: x = l.fs <= r.fs; break;411 case FCle: x = l.fs <= r.fs; break;
412 case FClt: x = l.fs < r.fs; break;412 case FClt: x = l.fs < r.fs; break;
413 case FCgt: x = l.fs > r.fs; break;413 case FCgt: x = l.fs > r.fs; break;
@@ -419,8 +419,8 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 5 unmodified lines
419 default: die("unreachable");419 default: die("unreachable");
420 }420 }
421 }421 }
422 else if (OCmpd <= op && op <= OCmpd1) {422 else if (Ocmpd <= op && op <= Ocmpd1) {
423 switch (op - OCmpd) {423 switch (op - Ocmpd) {
424 case FCle: x = l.fd <= r.fd; break;424 case FCle: x = l.fd <= r.fd; break;
425 case FClt: x = l.fd < r.fd; break;425 case FClt: x = l.fd < r.fd; break;
426 case FCgt: x = l.fd > r.fd; break;426 case FCgt: x = l.fd > r.fd; break;
@@ -453,13 +453,13 @@ foldflt(Con *res, int op, int w, Con *cl, Con *cr) · 26 unmodified lines
453 ld = cl->bits.d;453 ld = cl->bits.d;
454 rd = cr->bits.d;454 rd = cr->bits.d;
455 switch (op) {455 switch (op) {
456 case OAdd: xd = ld + rd; break;456 case Oadd: xd = ld + rd; break;
457 case OSub: xd = ld - rd; break;457 case Osub: xd = ld - rd; break;
458 case ODiv: xd = ld / rd; break;458 case Odiv: xd = ld / rd; break;
459 case OMul: xd = ld * rd; break;459 case Omul: xd = ld * rd; break;
460 case OSitof: xd = cl->bits.i; break;460 case Ositof: xd = cl->bits.i; break;
461 case OExts: xd = cl->bits.s; break;461 case Oexts: xd = cl->bits.s; break;
462 case OCast: xd = ld; break;462 case Ocast: xd = ld; break;
463 default: die("unreachable");463 default: die("unreachable");
464 }464 }
465 *res = (Con){CBits, .bits={.d=xd}, .flt=2};465 *res = (Con){CBits, .bits={.d=xd}, .flt=2};
@@ -467,13 +467,13 @@ foldflt(Con *res, int op, int w, Con *cl, Con *cr) · 1 unmodified line
467 ls = cl->bits.s;467 ls = cl->bits.s;
468 rs = cr->bits.s;468 rs = cr->bits.s;
469 switch (op) {469 switch (op) {
470 case OAdd: xs = ls + rs; break;470 case Oadd: xs = ls + rs; break;
471 case OSub: xs = ls - rs; break;471 case Osub: xs = ls - rs; break;
472 case ODiv: xs = ls / rs; break;472 case Odiv: xs = ls / rs; break;
473 case OMul: xs = ls * rs; break;473 case Omul: xs = ls * rs; break;
474 case OSitof: xs = cl->bits.i; break;474 case Ositof: xs = cl->bits.i; break;
475 case OTruncd: xs = cl->bits.d; break;475 case Otruncd: xs = cl->bits.d; break;
476 case OCast: xs = ls; break;476 case Ocast: xs = ls; break;
477 default: die("unreachable");477 default: die("unreachable");
478 }478 }
479 *res = (Con){CBits, .bits={.s=xs}, .flt=1};479 *res = (Con){CBits, .bits={.s=xs}, .flt=1};
@@ -486,8 +486,8 @@ opfold(int op, int cls, Con *cl, Con *cr, Fn *fn) · 6 unmodified lines
486 int nc;486 int nc;
487 Con c;487 Con c;
488 488
489 if ((op == ODiv || op == OUDiv489 if ((op == Odiv || op == Oudiv
490 || op == ORem || op == OURem) && czero(cr, KWIDE(cls)))490 || op == Orem || op == Ourem) && czero(cr, KWIDE(cls)))
491 err("null divisor in '%s'", opdesc[op].name);491 err("null divisor in '%s'", opdesc[op].name);
492 if (cls == Kw || cls == Kl)492 if (cls == Kw || cls == Kl)
493 foldint(&c, op, cls == Kl, cl, cr);493 foldint(&c, op, cls == Kl, cl, cr);
isel.c+83−83
@@ -40,8 +40,8 @@ fcmptoi(int fc) · 39 unmodified lines
40 case FCge: return ICuge;40 case FCge: return ICuge;
41 case FCne: return ICne;41 case FCne: return ICne;
42 case FCeq: return ICeq;42 case FCeq: return ICeq;
43 case FCo: return ICXnp;43 case FCo: return ICxnp;
44 case FCuo: return ICXp;44 case FCuo: return ICxp;
45 }45 }
46}46}
47 47
@@ -50,20 +50,20 @@ iscmp(int op, int *pk, int *pc) · 2 unmodified lines
50{50{
51 int k, c;51 int k, c;
52 52
53 if (OCmpw <= op && op <= OCmpw1) {53 if (Ocmpw <= op && op <= Ocmpw1) {
54 c = op - OCmpw;54 c = op - Ocmpw;
55 k = Kw;55 k = Kw;
56 }56 }
57 else if (OCmpl <= op && op <= OCmpl1) {57 else if (Ocmpl <= op && op <= Ocmpl1) {
58 c = op - OCmpl;58 c = op - Ocmpl;
59 k = Kl;59 k = Kl;
60 }60 }
61 else if (OCmps <= op && op <= OCmps1) {61 else if (Ocmps <= op && op <= Ocmps1) {
62 c = fcmptoi(op - OCmps);62 c = fcmptoi(op - Ocmps);
63 k = Ks;63 k = Ks;
64 }64 }
65 else if (OCmpd <= op && op <= OCmpd1) {65 else if (Ocmpd <= op && op <= Ocmpd1) {
66 c = fcmptoi(op - OCmpd);66 c = fcmptoi(op - Ocmpd);
67 k = Kd;67 k = Kd;
68 }68 }
69 else69 else
@@ -141,7 +141,7 @@ fixarg(Ref *r, int k, int phi, Fn *fn) · 71 unmodified lines
141 * long temporary141 * long temporary
142 */142 */
143 r1 = newtmp("isel", Kl, fn);143 r1 = newtmp("isel", Kl, fn);
144 emit(OCopy, Kl, r1, r0, R);144 emit(Ocopy, Kl, r1, r0, R);
145 }145 }
146 else if (s != -1) {146 else if (s != -1) {
147 /* load fast locals' addresses into147 /* load fast locals' addresses into
@@ -149,7 +149,7 @@ fixarg(Ref *r, int k, int phi, Fn *fn) · 1 unmodified line
149 * instruction149 * instruction
150 */150 */
151 r1 = newtmp("isel", Kl, fn);151 r1 = newtmp("isel", Kl, fn);
152 emit(OAddr, Kl, r1, SLOT(s), R);152 emit(Oaddr, Kl, r1, SLOT(s), R);
153 }153 }
154 *r = r1;154 *r = r1;
155}155}
@@ -190,7 +190,7 @@ selcmp(Ref arg[2], int k, Fn *fn) · 34 unmodified lines
190 arg[0] = r;190 arg[0] = r;
191 }191 }
192 assert(rtype(arg[0]) != RCon);192 assert(rtype(arg[0]) != RCon);
193 emit(OXCmp, k, R, arg[1], arg[0]);193 emit(Oxcmp, k, R, arg[1], arg[0]);
194 iarg = curi->arg;194 iarg = curi->arg;
195 fixarg(&iarg[0], k, 0, fn);195 fixarg(&iarg[0], k, 0, fn);
196 fixarg(&iarg[1], k, 0, fn);196 fixarg(&iarg[1], k, 0, fn);
@@ -214,16 +214,16 @@ sel(Ins i, ANum *an, Fn *fn) · 17 unmodified lines
214 i0 = curi;214 i0 = curi;
215 k = i.cls;215 k = i.cls;
216 switch (i.op) {216 switch (i.op) {
217 case ODiv:217 case Odiv:
218 case ORem:218 case Orem:
219 case OUDiv:219 case Oudiv:
220 case OURem:220 case Ourem:
221 if (i.op == ODiv || i.op == OUDiv)221 if (i.op == Odiv || i.op == Oudiv)
222 r0 = TMP(RAX), r1 = TMP(RDX);222 r0 = TMP(RAX), r1 = TMP(RDX);
223 else223 else
224 r0 = TMP(RDX), r1 = TMP(RAX);224 r0 = TMP(RDX), r1 = TMP(RAX);
225 emit(OCopy, k, i.to, r0, R);225 emit(Ocopy, k, i.to, r0, R);
226 emit(OCopy, k, R, r1, R);226 emit(Ocopy, k, R, r1, R);
227 if (rtype(i.arg[1]) == RCon) {227 if (rtype(i.arg[1]) == RCon) {
228 /* immediates not allowed for228 /* immediates not allowed for
229 * divisions in x86229 * divisions in x86
@@ -234,63 +234,63 @@ sel(Ins i, ANum *an, Fn *fn) · 4 unmodified lines
234 if (fn->tmp[r0.val].slot != -1)234 if (fn->tmp[r0.val].slot != -1)
235 err("unlikely argument %%%s in %s",235 err("unlikely argument %%%s in %s",
236 fn->tmp[r0.val].name, opdesc[i.op].name);236 fn->tmp[r0.val].name, opdesc[i.op].name);
237 if (i.op == ODiv || i.op == ORem) {237 if (i.op == Odiv || i.op == Orem) {
238 emit(OXIDiv, k, R, r0, R);238 emit(Oxidiv, k, R, r0, R);
239 emit(OSign, k, TMP(RDX), TMP(RAX), R);239 emit(Osign, k, TMP(RDX), TMP(RAX), R);
240 } else {240 } else {
241 emit(OXDiv, k, R, r0, R);241 emit(Oxdiv, k, R, r0, R);
242 emit(OCopy, k, TMP(RDX), CON_Z, R);242 emit(Ocopy, k, TMP(RDX), CON_Z, R);
243 }243 }
244 emit(OCopy, k, TMP(RAX), i.arg[0], R);244 emit(Ocopy, k, TMP(RAX), i.arg[0], R);
245 fixarg(&curi->arg[0], k, 0, fn);245 fixarg(&curi->arg[0], k, 0, fn);
246 if (rtype(i.arg[1]) == RCon)246 if (rtype(i.arg[1]) == RCon)
247 emit(OCopy, k, r0, i.arg[1], R);247 emit(Ocopy, k, r0, i.arg[1], R);
248 break;248 break;
249 case OSar:249 case Osar:
250 case OShr:250 case Oshr:
251 case OShl:251 case Oshl:
252 if (rtype(i.arg[1]) == RCon)252 if (rtype(i.arg[1]) == RCon)
253 goto Emit;253 goto Emit;
254 r0 = i.arg[1];254 r0 = i.arg[1];
255 i.arg[1] = TMP(RCX);255 i.arg[1] = TMP(RCX);
256 emit(OCopy, Kw, R, TMP(RCX), R);256 emit(Ocopy, Kw, R, TMP(RCX), R);
257 emiti(i);257 emiti(i);
258 emit(OCopy, Kw, TMP(RCX), r0, R);258 emit(Ocopy, Kw, TMP(RCX), r0, R);
259 break;259 break;
260 case ONop:260 case Onop:
261 break;261 break;
262 case OStored:262 case Ostored:
263 case OStores:263 case Ostores:
264 case OStorel:264 case Ostorel:
265 case OStorew:265 case Ostorew:
266 case OStoreh:266 case Ostoreh:
267 case OStoreb:267 case Ostoreb:
268 if (rtype(i.arg[0]) == RCon) {268 if (rtype(i.arg[0]) == RCon) {
269 if (i.op == OStored)269 if (i.op == Ostored)
270 i.op = OStorel;270 i.op = Ostorel;
271 if (i.op == OStores)271 if (i.op == Ostores)
272 i.op = OStorew;272 i.op = Ostorew;
273 }273 }
274 seladdr(&i.arg[1], an, fn);274 seladdr(&i.arg[1], an, fn);
275 goto Emit;275 goto Emit;
276 case_OLoad:276 case_Oload:
277 seladdr(&i.arg[0], an, fn);277 seladdr(&i.arg[0], an, fn);
278 goto Emit;278 goto Emit;
279 case OCall:279 case Ocall:
280 case OSAlloc:280 case Osalloc:
281 case OCopy:281 case Ocopy:
282 case OAdd:282 case Oadd:
283 case OSub:283 case Osub:
284 case OMul:284 case Omul:
285 case OAnd:285 case Oand:
286 case OOr:286 case Oor:
287 case OXor:287 case Oxor:
288 case OXTest:288 case Oxtest:
289 case OFtosi:289 case Oftosi:
290 case OSitof:290 case Ositof:
291 case OExts:291 case Oexts:
292 case OTruncd:292 case Otruncd:
293 case OCast:293 case Ocast:
294 case_OExt:294 case_OExt:
295Emit:295Emit:
296 emiti(i);296 emiti(i);
@@ -298,9 +298,9 @@ Emit: · 1 unmodified line
298 fixarg(&iarg[0], argcls(&i, 0), 0, fn);298 fixarg(&iarg[0], argcls(&i, 0), 0, fn);
299 fixarg(&iarg[1], argcls(&i, 1), 0, fn);299 fixarg(&iarg[1], argcls(&i, 1), 0, fn);
300 break;300 break;
301 case OAlloc:301 case Oalloc:
302 case OAlloc+1:302 case Oalloc+1:
303 case OAlloc+2: /* == OAlloc1 */303 case Oalloc+2: /* == Oalloc1 */
304 /* we need to make sure304 /* we need to make sure
305 * the stack remains aligned305 * the stack remains aligned
306 * (rsp = 0) mod 16306 * (rsp = 0) mod 16
@@ -310,14 +310,14 @@ Emit: · 3 unmodified lines
310 if (sz < 0 || sz >= INT_MAX-15)310 if (sz < 0 || sz >= INT_MAX-15)
311 err("invalid alloc size %"PRId64, sz);311 err("invalid alloc size %"PRId64, sz);
312 sz = (sz + 15) & -16;312 sz = (sz + 15) & -16;
313 emit(OSAlloc, Kl, i.to, getcon(sz, fn), R);313 emit(Osalloc, Kl, i.to, getcon(sz, fn), R);
314 } else {314 } else {
315 /* r0 = (i.arg[0] + 15) & -16 */315 /* r0 = (i.arg[0] + 15) & -16 */
316 r0 = newtmp("isel", Kl, fn);316 r0 = newtmp("isel", Kl, fn);
317 r1 = newtmp("isel", Kl, fn);317 r1 = newtmp("isel", Kl, fn);
318 emit(OSAlloc, Kl, i.to, r0, R);318 emit(Osalloc, Kl, i.to, r0, R);
319 emit(OAnd, Kl, r0, r1, getcon(-16, fn));319 emit(Oand, Kl, r0, r1, getcon(-16, fn));
320 emit(OAdd, Kl, r1, i.arg[0], getcon(15, fn));320 emit(Oadd, Kl, r1, i.arg[0], getcon(15, fn));
321 if (fn->tmp[i.arg[0].val].slot != -1)321 if (fn->tmp[i.arg[0].val].slot != -1)
322 err("unlikely argument %%%s in %s",322 err("unlikely argument %%%s in %s",
323 fn->tmp[i.arg[0].val].name, opdesc[i.op].name);323 fn->tmp[i.arg[0].val].name, opdesc[i.op].name);
@@ -327,11 +327,11 @@ Emit: · 3 unmodified lines
327 if (isext(i.op))327 if (isext(i.op))
328 goto case_OExt;328 goto case_OExt;
329 if (isload(i.op))329 if (isload(i.op))
330 goto case_OLoad;330 goto case_Oload;
331 if (iscmp(i.op, &kc, &x)) {331 if (iscmp(i.op, &kc, &x)) {
332 if (rtype(i.arg[0]) == RCon)332 if (rtype(i.arg[0]) == RCon)
333 x = icmpop(x);333 x = icmpop(x);
334 emit(OXSet+x, k, i.to, R, R);334 emit(Oxset+x, k, i.to, R, R);
335 selcmp(i.arg, kc, fn);335 selcmp(i.arg, kc, fn);
336 break;336 break;
337 }337 }
@@ -365,14 +365,14 @@ seljmp(Blk *b, Fn *fn) · 27 unmodified lines
365 int c, k;365 int c, k;
366 Ins *fi;366 Ins *fi;
367 367
368 if (b->jmp.type == JRet0 || b->jmp.type == JJmp)368 if (b->jmp.type == Jret0 || b->jmp.type == Jjmp)
369 return;369 return;
370 assert(b->jmp.type == JJnz);370 assert(b->jmp.type == Jjnz);
371 r = b->jmp.arg;371 r = b->jmp.arg;
372 b->jmp.arg = R;372 b->jmp.arg = R;
373 assert(!req(r, R) && rtype(r) != RCon);373 assert(!req(r, R) && rtype(r) != RCon);
374 if (b->s1 == b->s2) {374 if (b->s1 == b->s2) {
375 b->jmp.type = JJmp;375 b->jmp.type = Jjmp;
376 b->s2 = 0;376 b->s2 = 0;
377 return;377 return;
378 }378 }
@@ -381,20 +381,20 @@ seljmp(Blk *b, Fn *fn) · 2 unmodified lines
381 if (iscmp(fi->op, &k, &c)) {381 if (iscmp(fi->op, &k, &c)) {
382 if (rtype(fi->arg[0]) == RCon)382 if (rtype(fi->arg[0]) == RCon)
383 c = icmpop(c);383 c = icmpop(c);
384 b->jmp.type = JXJc + c;384 b->jmp.type = Jxjc + c;
385 if (fn->tmp[r.val].nuse == 1) {385 if (fn->tmp[r.val].nuse == 1) {
386 assert(fn->tmp[r.val].ndef == 1);386 assert(fn->tmp[r.val].ndef == 1);
387 selcmp(fi->arg, k, fn);387 selcmp(fi->arg, k, fn);
388 *fi = (Ins){.op = ONop};388 *fi = (Ins){.op = Onop};
389 }389 }
390 return;390 return;
391 }391 }
392 if (fi->op == OAnd && fn->tmp[r.val].nuse == 1392 if (fi->op == Oand && fn->tmp[r.val].nuse == 1
393 && (rtype(fi->arg[0]) == RTmp ||393 && (rtype(fi->arg[0]) == RTmp ||
394 rtype(fi->arg[1]) == RTmp)) {394 rtype(fi->arg[1]) == RTmp)) {
395 fi->op = OXTest;395 fi->op = Oxtest;
396 fi->to = R;396 fi->to = R;
397 b->jmp.type = JXJc + ICne;397 b->jmp.type = Jxjc + ICne;
398 if (rtype(fi->arg[1]) == RCon) {398 if (rtype(fi->arg[1]) == RCon) {
399 r = fi->arg[1];399 r = fi->arg[1];
400 fi->arg[1] = fi->arg[0];400 fi->arg[1] = fi->arg[0];
@@ -407,12 +407,12 @@ seljmp(Blk *b, Fn *fn) · 6 unmodified lines
407 * has to be marked as live407 * has to be marked as live
408 */408 */
409 if (fn->tmp[r.val].nuse == 1)409 if (fn->tmp[r.val].nuse == 1)
410 emit(OCopy, Kw, R, r, R);410 emit(Ocopy, Kw, R, r, R);
411 b->jmp.type = JXJc + ICne;411 b->jmp.type = Jxjc + ICne;
412 return;412 return;
413 }413 }
414 selcmp((Ref[2]){r, CON_Z}, Kw, fn); /* todo, add long branch if non-zero */414 selcmp((Ref[2]){r, CON_Z}, Kw, fn); /* todo, add long branch if non-zero */
415 b->jmp.type = JXJc + ICne;415 b->jmp.type = Jxjc + ICne;
416}416}
417 417
418static int418static int
@@ -474,13 +474,13 @@ anumber(ANum *ai, Blk *b, Con *con) · 55 unmodified lines
474 for (i=b->ins; i-b->ins < b->nins; i++) {474 for (i=b->ins; i-b->ins < b->nins; i++) {
475 if (rtype(i->to) == RTmp)475 if (rtype(i->to) == RTmp)
476 ai[i->to.val].i = i;476 ai[i->to.val].i = i;
477 if (i->op != OAdd && i->op != OMul)477 if (i->op != Oadd && i->op != Omul)
478 continue;478 continue;
479 a1 = aref(i->arg[0], ai);479 a1 = aref(i->arg[0], ai);
480 a2 = aref(i->arg[1], ai);480 a2 = aref(i->arg[1], ai);
481 t1 = a1 != 1 && a1 != 2;481 t1 = a1 != 1 && a1 != 2;
482 t2 = a2 != 1 && a2 != 2;482 t2 = a2 != 1 && a2 != 2;
483 if (i->op == OAdd) {483 if (i->op == Oadd) {
484 a = add[n1 = a1][n2 = a2];484 a = add[n1 = a1][n2 = a2];
485 if (t1 && a < add[0][a2])485 if (t1 && a < add[0][a2])
486 a = add[n1 = 0][n2 = a2];486 a = add[n1 = 0][n2 = a2];
@@ -586,7 +586,7 @@ isel(Fn *fn) · 99 unmodified lines
586 /* assign slots to fast allocs */586 /* assign slots to fast allocs */
587 b = fn->start;587 b = fn->start;
588 /* specific to NAlign == 3 */ /* or change n=4 and sz /= 4 below */588 /* specific to NAlign == 3 */ /* or change n=4 and sz /= 4 below */
589 for (al=OAlloc, n=4; al<=OAlloc1; al++, n*=2)589 for (al=Oalloc, n=4; al<=Oalloc1; al++, n*=2)
590 for (i=b->ins; i-b->ins < b->nins; i++)590 for (i=b->ins; i-b->ins < b->nins; i++)
591 if (i->op == al) {591 if (i->op == al) {
592 if (rtype(i->arg[0]) != RCon)592 if (rtype(i->arg[0]) != RCon)
@@ -598,7 +598,7 @@ isel(Fn *fn) · 5 unmodified lines
598 sz /= 4;598 sz /= 4;
599 fn->tmp[i->to.val].slot = fn->slot;599 fn->tmp[i->to.val].slot = fn->slot;
600 fn->slot += sz;600 fn->slot += sz;
601 *i = (Ins){.op = ONop};601 *i = (Ins){.op = Onop};
602 }602 }
603 603
604 /* process basic blocks */604 /* process basic blocks */
live.c+1−1
@@ -115,7 +115,7 @@ Again: · 114 unmodified lines
115 for (k=0; k<2; k++)115 for (k=0; k<2; k++)
116 b->nlive[k] = nlv[k];116 b->nlive[k] = nlv[k];
117 for (i=&b->ins[b->nins]; i!=b->ins;) {117 for (i=&b->ins[b->nins]; i!=b->ins;) {
118 if ((--i)->op == OCall && rtype(i->arg[1]) == RCall) {118 if ((--i)->op == Ocall && rtype(i->arg[1]) == RCall) {
119 b->in->t[0] &= ~retregs(i->arg[1], m);119 b->in->t[0] &= ~retregs(i->arg[1], m);
120 for (k=0; k<2; k++)120 for (k=0; k<2; k++)
121 nlv[k] -= m[k];121 nlv[k] -= m[k];
mem.c+17−17
@@ -4,10 +4,10 @@ static int · 3 unmodified lines
4loadsz(Ins *l)4loadsz(Ins *l)
5{5{
6 switch (l->op) {6 switch (l->op) {
7 case OLoadsb: case OLoadub: return 1;7 case Oloadsb: case Oloadub: return 1;
8 case OLoadsh: case OLoaduh: return 2;8 case Oloadsh: case Oloaduh: return 2;
9 case OLoadsw: case OLoaduw: return 4;9 case Oloadsw: case Oloaduw: return 4;
10 case OLoad: return KWIDE(l->cls) ? 8 : 4;10 case Oload: return KWIDE(l->cls) ? 8 : 4;
11 }11 }
12 die("unreachable");12 die("unreachable");
13}13}
@@ -16,10 +16,10 @@ static int · 2 unmodified lines
16storesz(Ins *s)16storesz(Ins *s)
17{17{
18 switch (s->op) {18 switch (s->op) {
19 case OStoreb: return 1;19 case Ostoreb: return 1;
20 case OStoreh: return 2;20 case Ostoreh: return 2;
21 case OStorew: case OStores: return 4;21 case Ostorew: case Ostores: return 4;
22 case OStorel: case OStored: return 8;22 case Ostorel: case Ostored: return 8;
23 }23 }
24 die("unreachable");24 die("unreachable");
25}25}
@@ -38,7 +38,7 @@ memopt(Fn *fn) · 12 unmodified lines
38 /* promote uniform stack slots to temporaries */38 /* promote uniform stack slots to temporaries */
39 b = fn->start;39 b = fn->start;
40 for (i=b->ins; i-b->ins < b->nins; i++) {40 for (i=b->ins; i-b->ins < b->nins; i++) {
41 if (OAlloc > i->op || i->op > OAlloc1)41 if (Oalloc > i->op || i->op > Oalloc1)
42 continue;42 continue;
43 /* specific to NAlign == 3 */43 /* specific to NAlign == 3 */
44 assert(rtype(i->to) == RTmp);44 assert(rtype(i->to) == RTmp);
@@ -67,14 +67,14 @@ memopt(Fn *fn) · 22 unmodified lines
67 goto Skip;67 goto Skip;
68 }68 }
69 /* get rid of the alloc and replace uses */69 /* get rid of the alloc and replace uses */
70 *i = (Ins){.op = ONop};70 *i = (Ins){.op = Onop};
71 t->ndef--;71 t->ndef--;
72 ue = &t->use[t->nuse];72 ue = &t->use[t->nuse];
73 for (u=t->use; u!=ue; u++) {73 for (u=t->use; u!=ue; u++) {
74 l = u->u.ins;74 l = u->u.ins;
75 if (isstore(l->op)) {75 if (isstore(l->op)) {
76 l->cls = k;76 l->cls = k;
77 l->op = OCopy;77 l->op = Ocopy;
78 l->to = l->arg[1];78 l->to = l->arg[1];
79 l->arg[1] = R;79 l->arg[1] = R;
80 t->nuse--;80 t->nuse--;
@@ -86,16 +86,16 @@ memopt(Fn *fn) · 5 unmodified lines
86 /* try to turn loads into copies so we86 /* try to turn loads into copies so we
87 * can eliminate them later */87 * can eliminate them later */
88 switch(l->op) {88 switch(l->op) {
89 case OLoad:89 case Oload:
90 case OLoadsw:90 case Oloadsw:
91 case OLoaduw:91 case Oloaduw:
92 if (KBASE(k) != KBASE(l->cls))92 if (KBASE(k) != KBASE(l->cls))
93 l->op = OCast;93 l->op = Ocast;
94 else94 else
95 l->op = OCopy;95 l->op = Ocopy;
96 break;96 break;
97 default:97 default:
98 l->op = OExtsb + (l->op - OLoadsb);98 l->op = Oextsb + (l->op - Oloadsb);
99 break;99 break;
100 }100 }
101 }101 }
parse.c+114−114
@@ -11,72 +11,72 @@ OpDesc opdesc[NOp] = { · 10 unmodified lines
11#define A(a,b,c,d) {[Kw]=K##a, [Kl]=K##b, [Ks]=K##c, [Kd]=K##d}11#define A(a,b,c,d) {[Kw]=K##a, [Kl]=K##b, [Ks]=K##c, [Kd]=K##d}
12 12
13 /* NAME NM ARGCLS0 ARGCLS1 SF LF FLD*/13 /* NAME NM ARGCLS0 ARGCLS1 SF LF FLD*/
14 [OAdd] = { "add", 2, {A(w,l,s,d), A(w,l,s,d)}, 1, 0, 1 },14 [Oadd] = { "add", 2, {A(w,l,s,d), A(w,l,s,d)}, 1, 0, 1 },
15 [OSub] = { "sub", 2, {A(w,l,s,d), A(w,l,s,d)}, 1, 0, 1 },15 [Osub] = { "sub", 2, {A(w,l,s,d), A(w,l,s,d)}, 1, 0, 1 },
16 [ODiv] = { "div", 2, {A(w,l,s,d), A(w,l,s,d)}, 0, 0, 1 },16 [Odiv] = { "div", 2, {A(w,l,s,d), A(w,l,s,d)}, 0, 0, 1 },
17 [ORem] = { "rem", 2, {A(w,l,e,e), A(w,l,e,e)}, 0, 0, 1 },17 [Orem] = { "rem", 2, {A(w,l,e,e), A(w,l,e,e)}, 0, 0, 1 },
18 [OUDiv] = { "udiv", 2, {A(w,l,e,e), A(w,l,e,e)}, 0, 0, 1 },18 [Oudiv] = { "udiv", 2, {A(w,l,e,e), A(w,l,e,e)}, 0, 0, 1 },
19 [OURem] = { "urem", 2, {A(w,l,e,e), A(w,l,e,e)}, 0, 0, 1 },19 [Ourem] = { "urem", 2, {A(w,l,e,e), A(w,l,e,e)}, 0, 0, 1 },
20 [OMul] = { "mul", 2, {A(w,l,s,d), A(w,l,s,d)}, 0, 0, 1 },20 [Omul] = { "mul", 2, {A(w,l,s,d), A(w,l,s,d)}, 0, 0, 1 },
21 [OAnd] = { "and", 2, {A(w,l,e,e), A(w,l,e,e)}, 1, 0, 1 },21 [Oand] = { "and", 2, {A(w,l,e,e), A(w,l,e,e)}, 1, 0, 1 },
22 [OOr] = { "or", 2, {A(w,l,e,e), A(w,l,e,e)}, 1, 0, 1 },22 [Oor] = { "or", 2, {A(w,l,e,e), A(w,l,e,e)}, 1, 0, 1 },
23 [OXor] = { "xor", 2, {A(w,l,e,e), A(w,l,e,e)}, 1, 0, 1 },23 [Oxor] = { "xor", 2, {A(w,l,e,e), A(w,l,e,e)}, 1, 0, 1 },
24 [OSar] = { "sar", 1, {A(w,l,e,e), A(w,w,e,e)}, 1, 0, 1 },24 [Osar] = { "sar", 1, {A(w,l,e,e), A(w,w,e,e)}, 1, 0, 1 },
25 [OShr] = { "shr", 1, {A(w,l,e,e), A(w,w,e,e)}, 1, 0, 1 },25 [Oshr] = { "shr", 1, {A(w,l,e,e), A(w,w,e,e)}, 1, 0, 1 },
26 [OShl] = { "shl", 1, {A(w,l,e,e), A(w,w,e,e)}, 1, 0, 1 },26 [Oshl] = { "shl", 1, {A(w,l,e,e), A(w,w,e,e)}, 1, 0, 1 },
27 [OStored] = { "stored", 0, {A(d,d,d,d), A(m,m,m,m)}, 0, 1, 0 },27 [Ostored] = { "stored", 0, {A(d,d,d,d), A(m,m,m,m)}, 0, 1, 0 },
28 [OStores] = { "stores", 0, {A(s,s,s,s), A(m,m,m,m)}, 0, 1, 0 },28 [Ostores] = { "stores", 0, {A(s,s,s,s), A(m,m,m,m)}, 0, 1, 0 },
29 [OStorel] = { "storel", 0, {A(l,l,l,l), A(m,m,m,m)}, 0, 1, 0 },29 [Ostorel] = { "storel", 0, {A(l,l,l,l), A(m,m,m,m)}, 0, 1, 0 },
30 [OStorew] = { "storew", 0, {A(w,w,w,w), A(m,m,m,m)}, 0, 1, 0 },30 [Ostorew] = { "storew", 0, {A(w,w,w,w), A(m,m,m,m)}, 0, 1, 0 },
31 [OStoreh] = { "storeh", 0, {A(w,w,w,w), A(m,m,m,m)}, 0, 1, 0 },31 [Ostoreh] = { "storeh", 0, {A(w,w,w,w), A(m,m,m,m)}, 0, 1, 0 },
32 [OStoreb] = { "storeb", 0, {A(w,w,w,w), A(m,m,m,m)}, 0, 1, 0 },32 [Ostoreb] = { "storeb", 0, {A(w,w,w,w), A(m,m,m,m)}, 0, 1, 0 },
33 [OLoad] = { "load", 0, {A(m,m,m,m), A(x,x,x,x)}, 0, 1, 0 },33 [Oload] = { "load", 0, {A(m,m,m,m), A(x,x,x,x)}, 0, 1, 0 },
34 [OLoadsw] = { "loadsw", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },34 [Oloadsw] = { "loadsw", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },
35 [OLoaduw] = { "loaduw", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },35 [Oloaduw] = { "loaduw", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },
36 [OLoadsh] = { "loadsh", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },36 [Oloadsh] = { "loadsh", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },
37 [OLoaduh] = { "loaduh", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },37 [Oloaduh] = { "loaduh", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },
38 [OLoadsb] = { "loadsb", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },38 [Oloadsb] = { "loadsb", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },
39 [OLoadub] = { "loadub", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },39 [Oloadub] = { "loadub", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },
40 [OExtsw] = { "extsw", 0, {A(e,w,e,e), A(e,x,e,e)}, 0, 1, 1 },40 [Oextsw] = { "extsw", 0, {A(e,w,e,e), A(e,x,e,e)}, 0, 1, 1 },
41 [OExtuw] = { "extuw", 0, {A(e,w,e,e), A(e,x,e,e)}, 0, 1, 1 },41 [Oextuw] = { "extuw", 0, {A(e,w,e,e), A(e,x,e,e)}, 0, 1, 1 },
42 [OExtsh] = { "extsh", 0, {A(w,w,e,e), A(x,x,e,e)}, 0, 1, 1 },42 [Oextsh] = { "extsh", 0, {A(w,w,e,e), A(x,x,e,e)}, 0, 1, 1 },
43 [OExtuh] = { "extuh", 0, {A(w,w,e,e), A(x,x,e,e)}, 0, 1, 1 },43 [Oextuh] = { "extuh", 0, {A(w,w,e,e), A(x,x,e,e)}, 0, 1, 1 },
44 [OExtsb] = { "extsb", 0, {A(w,w,e,e), A(x,x,e,e)}, 0, 1, 1 },44 [Oextsb] = { "extsb", 0, {A(w,w,e,e), A(x,x,e,e)}, 0, 1, 1 },
45 [OExtub] = { "extub", 0, {A(w,w,e,e), A(x,x,e,e)}, 0, 1, 1 },45 [Oextub] = { "extub", 0, {A(w,w,e,e), A(x,x,e,e)}, 0, 1, 1 },
46 [OExts] = { "exts", 0, {A(e,e,e,s), A(e,e,e,x)}, 0, 1, 1 },46 [Oexts] = { "exts", 0, {A(e,e,e,s), A(e,e,e,x)}, 0, 1, 1 },
47 [OTruncd] = { "truncd", 0, {A(e,e,d,e), A(e,e,x,e)}, 0, 1, 1 },47 [Otruncd] = { "truncd", 0, {A(e,e,d,e), A(e,e,x,e)}, 0, 1, 1 },
48 [OFtosi] = { "ftosi", 0, {A(s,d,e,e), A(x,x,e,e)}, 0, 1, 1 },48 [Oftosi] = { "ftosi", 0, {A(s,d,e,e), A(x,x,e,e)}, 0, 1, 1 },
49 [OSitof] = { "sitof", 0, {A(e,e,w,l), A(e,e,x,x)}, 0, 1, 1 },49 [Ositof] = { "sitof", 0, {A(e,e,w,l), A(e,e,x,x)}, 0, 1, 1 },
50 [OCast] = { "cast", 0, {A(s,d,w,l), A(x,x,x,x)}, 0, 1, 1 },50 [Ocast] = { "cast", 0, {A(s,d,w,l), A(x,x,x,x)}, 0, 1, 1 },
51 [OCopy] = { "copy", 1, {A(w,l,s,d), A(x,x,x,x)}, 0, 1, 0 },51 [Ocopy] = { "copy", 1, {A(w,l,s,d), A(x,x,x,x)}, 0, 1, 0 },
52 [ONop] = { "nop", 0, {A(x,x,x,x), A(x,x,x,x)}, 0, 1, 0 },52 [Onop] = { "nop", 0, {A(x,x,x,x), A(x,x,x,x)}, 0, 1, 0 },
53 [OSwap] = { "swap", 2, {A(w,l,s,d), A(w,l,s,d)}, 0, 0, 0 },53 [Oswap] = { "swap", 2, {A(w,l,s,d), A(w,l,s,d)}, 0, 0, 0 },
54 [OSign] = { "sign", 0, {A(w,l,e,e), A(x,x,e,e)}, 0, 0, 0 },54 [Osign] = { "sign", 0, {A(w,l,e,e), A(x,x,e,e)}, 0, 0, 0 },
55 [OSAlloc] = { "salloc", 0, {A(e,l,e,e), A(e,x,e,e)}, 0, 0, 0 },55 [Osalloc] = { "salloc", 0, {A(e,l,e,e), A(e,x,e,e)}, 0, 0, 0 },
56 [OXIDiv] = { "xidiv", 1, {A(w,l,e,e), A(x,x,e,e)}, 0, 0, 0 },56 [Oxidiv] = { "xidiv", 1, {A(w,l,e,e), A(x,x,e,e)}, 0, 0, 0 },
57 [OXDiv] = { "xdiv", 1, {A(w,l,e,e), A(x,x,e,e)}, 0, 0, 0 },57 [Oxdiv] = { "xdiv", 1, {A(w,l,e,e), A(x,x,e,e)}, 0, 0, 0 },
58 [OXCmp] = { "xcmp", 1, {A(w,l,s,d), A(w,l,s,d)}, 1, 0, 0 },58 [Oxcmp] = { "xcmp", 1, {A(w,l,s,d), A(w,l,s,d)}, 1, 0, 0 },
59 [OXTest] = { "xtest", 1, {A(w,l,e,e), A(w,l,e,e)}, 1, 0, 0 },59 [Oxtest] = { "xtest", 1, {A(w,l,e,e), A(w,l,e,e)}, 1, 0, 0 },
60 [OAddr] = { "addr", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },60 [Oaddr] = { "addr", 0, {A(m,m,e,e), A(x,x,e,e)}, 0, 1, 0 },
61 [OPar] = { "parn", 0, {A(x,x,x,x), A(x,x,x,x)}, 0, 0, 0 },61 [Opar] = { "parn", 0, {A(x,x,x,x), A(x,x,x,x)}, 0, 0, 0 },
62 [OParc] = { "parc", 0, {A(e,x,e,e), A(e,x,e,e)}, 0, 0, 0 },62 [Oparc] = { "parc", 0, {A(e,x,e,e), A(e,x,e,e)}, 0, 0, 0 },
63 [OArg] = { "arg", 0, {A(w,l,s,d), A(x,x,x,x)}, 0, 0, 0 },63 [Oarg] = { "arg", 0, {A(w,l,s,d), A(x,x,x,x)}, 0, 0, 0 },
64 [OArgc] = { "argc", 0, {A(e,x,e,e), A(e,l,e,e)}, 0, 0, 0 },64 [Oargc] = { "argc", 0, {A(e,x,e,e), A(e,l,e,e)}, 0, 0, 0 },
65 [OCall] = { "call", 0, {A(m,m,m,m), A(x,x,x,x)}, 0, 0, 0 },65 [Ocall] = { "call", 0, {A(m,m,m,m), A(x,x,x,x)}, 0, 0, 0 },
66 [OXSetnp] = { "xsetnp", 0, {A(x,x,e,e), A(x,x,e,e)}, 0, 0, 0 },66 [Oxsetnp] = { "xsetnp", 0, {A(x,x,e,e), A(x,x,e,e)}, 0, 0, 0 },
67 [OXSetp] = { "xsetp", 0, {A(x,x,e,e), A(x,x,e,e)}, 0, 0, 0 },67 [Oxsetp] = { "xsetp", 0, {A(x,x,e,e), A(x,x,e,e)}, 0, 0, 0 },
68 [OAlloc] = { "alloc4", 1, {A(e,l,e,e), A(e,x,e,e)}, 0, 0, 0 },68 [Oalloc] = { "alloc4", 1, {A(e,l,e,e), A(e,x,e,e)}, 0, 0, 0 },
69 [OAlloc+1] = { "alloc8", 1, {A(e,l,e,e), A(e,x,e,e)}, 0, 0, 0 },69 [Oalloc+1] = { "alloc8", 1, {A(e,l,e,e), A(e,x,e,e)}, 0, 0, 0 },
70 [OAlloc+2] = { "alloc16", 1, {A(e,l,e,e), A(e,x,e,e)}, 0, 0, 0 },70 [Oalloc+2] = { "alloc16", 1, {A(e,l,e,e), A(e,x,e,e)}, 0, 0, 0 },
71#define X(c) \71#define X(c) \
72 [OCmpw+IC##c] = { "c" #c "w", 0, {A(w,w,e,e), A(w,w,e,e)}, 1, 0, 1 }, \72 [Ocmpw+IC##c] = { "c" #c "w", 0, {A(w,w,e,e), A(w,w,e,e)}, 1, 0, 1 }, \
73 [OCmpl+IC##c] = { "c" #c "l", 0, {A(l,l,e,e), A(l,l,e,e)}, 1, 0, 1 }, \73 [Ocmpl+IC##c] = { "c" #c "l", 0, {A(l,l,e,e), A(l,l,e,e)}, 1, 0, 1 }, \
74 [OXSet+IC##c] = { "xset" #c, 0, {A(x,x,e,e), A(x,x,e,e)}, 0, 1, 0 },74 [Oxset+IC##c] = { "xset" #c, 0, {A(x,x,e,e), A(x,x,e,e)}, 0, 1, 0 },
75 ICMPS(X)75 ICMPS(X)
76#undef X76#undef X
77#define X(c) \77#define X(c) \
78 [OCmps+FC##c] = { "c" #c "s", 0, {A(s,s,e,e), A(s,s,e,e)}, 1, 0, 1 }, \78 [Ocmps+FC##c] = { "c" #c "s", 0, {A(s,s,e,e), A(s,s,e,e)}, 1, 0, 1 }, \
79 [OCmpd+FC##c] = { "c" #c "d", 0, {A(d,d,e,e), A(d,d,e,e)}, 1, 0, 1 },79 [Ocmpd+FC##c] = { "c" #c "d", 0, {A(d,d,e,e), A(d,d,e,e)}, 1, 0, 1 },
80 FCMPS(X)80 FCMPS(X)
81#undef X81#undef X
82 82
@@ -191,12 +191,12 @@ lex() · 108 unmodified lines
191 { "d", TD },191 { "d", TD },
192 { "s", TS },192 { "s", TS },
193 { "z", TZ },193 { "z", TZ },
194 { "loadw", OLoad }, /* for convenience */194 { "loadw", Oload }, /* for convenience */
195 { "loadl", OLoad },195 { "loadl", Oload },
196 { "loads", OLoad },196 { "loads", Oload },
197 { "loadd", OLoad },197 { "loadd", Oload },
198 { "alloc1", OAlloc },198 { "alloc1", Oalloc },
199 { "alloc2", OAlloc },199 { "alloc2", Oalloc },
200 { 0, TXXX }200 { 0, TXXX }
201 };201 };
202 static char tok[NString];202 static char tok[NString];
@@ -453,14 +453,14 @@ parserefl(int arg) · 250 unmodified lines
453 err("invalid function parameter");453 err("invalid function parameter");
454 if (k == 4)454 if (k == 4)
455 if (arg)455 if (arg)
456 *curi = (Ins){OArgc, R, {TYPE(ty), r}, Kl};456 *curi = (Ins){Oargc, R, {TYPE(ty), r}, Kl};
457 else457 else
458 *curi = (Ins){OParc, r, {TYPE(ty)}, Kl};458 *curi = (Ins){Oparc, r, {TYPE(ty)}, Kl};
459 else459 else
460 if (arg)460 if (arg)
461 *curi = (Ins){OArg, R, {r}, k};461 *curi = (Ins){Oarg, R, {r}, k};
462 else462 else
463 *curi = (Ins){OPar, r, {R}, k};463 *curi = (Ins){Opar, r, {R}, k};
464 curi++;464 curi++;
465 if (peek() == TRParen)465 if (peek() == TRParen)
466 break;466 break;
@@ -522,12 +522,12 @@ parseline(PState ps) · 55 unmodified lines
522 break;522 break;
523 case TLbl:523 case TLbl:
524 b = findblk(tokval.str);524 b = findblk(tokval.str);
525 if (curb && curb->jmp.type == JXXX) {525 if (curb && curb->jmp.type == Jxxx) {
526 closeblk();526 closeblk();
527 curb->jmp.type = JJmp;527 curb->jmp.type = Jjmp;
528 curb->s1 = b;528 curb->s1 = b;
529 }529 }
530 if (b->jmp.type != JXXX)530 if (b->jmp.type != Jxxx)
531 err("multiple definitions of block @%s", b->name);531 err("multiple definitions of block @%s", b->name);
532 *blink = b;532 *blink = b;
533 curb = b;533 curb = b;
@@ -536,9 +536,9 @@ parseline(PState ps) · 2 unmodified lines
536 return PPhi;536 return PPhi;
537 case TRet:537 case TRet:
538 curb->jmp.type = (int[]){538 curb->jmp.type = (int[]){
539 JRetw, JRetl,539 Jretw, Jretl,
540 JRets, JRetd,540 Jrets, Jretd,
541 JRetc, JRet0541 Jretc, Jret0
542 }[rcls];542 }[rcls];
543 if (rcls < 5) {543 if (rcls < 5) {
544 r = parseref();544 r = parseref();
@@ -548,10 +548,10 @@ parseline(PState ps) · 3 unmodified lines
548 }548 }
549 goto Close;549 goto Close;
550 case TJmp:550 case TJmp:
551 curb->jmp.type = JJmp;551 curb->jmp.type = Jjmp;
552 goto Jump;552 goto Jump;
553 case TJnz:553 case TJnz:
554 curb->jmp.type = JJnz;554 curb->jmp.type = Jjnz;
555 r = parseref();555 r = parseref();
556 if (req(r, R))556 if (req(r, R))
557 err("invalid argument for jnz jump");557 err("invalid argument for jnz jump");
@@ -560,7 +560,7 @@ parseline(PState ps) · 2 unmodified lines
560 Jump:560 Jump:
561 expect(TLbl);561 expect(TLbl);
562 curb->s1 = findblk(tokval.str);562 curb->s1 = findblk(tokval.str);
563 if (curb->jmp.type != JJmp) {563 if (curb->jmp.type != Jjmp) {
564 expect(TComma);564 expect(TComma);
565 expect(TLbl);565 expect(TLbl);
566 curb->s2 = findblk(tokval.str);566 curb->s2 = findblk(tokval.str);
@@ -586,7 +586,7 @@ DoOp: · 19 unmodified lines
586 arg[0] = parseref();586 arg[0] = parseref();
587 parserefl(1);587 parserefl(1);
588 expect(TNL);588 expect(TNL);
589 op = OCall;589 op = Ocall;
590 if (k == 4) {590 if (k == 4) {
591 k = Kl;591 k = Kl;
592 arg[1] = TYPE(ty);592 arg[1] = TYPE(ty);
@@ -721,19 +721,19 @@ typecheck(Fn *fn) · 128 unmodified lines
721 }721 }
722 r = b->jmp.arg;722 r = b->jmp.arg;
723 if (isret(b->jmp.type)) {723 if (isret(b->jmp.type)) {
724 if (b->jmp.type == JRetc) {724 if (b->jmp.type == Jretc) {
725 if (!usecheck(r, Kl, fn))725 if (!usecheck(r, Kl, fn))
726 goto JErr;726 goto JErr;
727 } else if (!usecheck(r, b->jmp.type-JRetw, fn))727 } else if (!usecheck(r, b->jmp.type-Jretw, fn))
728 goto JErr;728 goto JErr;
729 }729 }
730 if (b->jmp.type == JJnz && !usecheck(r, Kw, fn))730 if (b->jmp.type == Jjnz && !usecheck(r, Kw, fn))
731 JErr:731 JErr:
732 err("invalid type for jump argument %%%s in block @%s",732 err("invalid type for jump argument %%%s in block @%s",
733 fn->tmp[r.val].name, b->name);733 fn->tmp[r.val].name, b->name);
734 if (b->s1 && b->s1->jmp.type == JXXX)734 if (b->s1 && b->s1->jmp.type == Jxxx)
735 err("block @%s is used undefined", b->s1->name);735 err("block @%s is used undefined", b->s1->name);
736 if (b->s2 && b->s2->jmp.type == JXXX)736 if (b->s2 && b->s2->jmp.type == Jxxx)
737 err("block @%s is used undefined", b->s2->name);737 err("block @%s is used undefined", b->s2->name);
738 }738 }
739}739}
@@ -775,7 +775,7 @@ parsefn(int export) · 35 unmodified lines
775 while (ps != PEnd);775 while (ps != PEnd);
776 if (!curb)776 if (!curb)
777 err("empty function");777 err("empty function");
778 if (curb->jmp.type == JXXX)778 if (curb->jmp.type == Jxxx)
779 err("last block misses jump");779 err("last block misses jump");
780 curf->mem = vnew(0, sizeof curf->mem[0]);780 curf->mem = vnew(0, sizeof curf->mem[0]);
781 curf->nmem = 0;781 curf->nmem = 0;
@@ -1086,26 +1086,26 @@ void · 304 unmodified lines
1086printfn(Fn *fn, FILE *f)1086printfn(Fn *fn, FILE *f)
1087{1087{
1088 static char *jtoa[NJmp] = {1088 static char *jtoa[NJmp] = {
1089 [JRet0] = "ret",1089 [Jret0] = "ret",
1090 [JRetw] = "retw",1090 [Jretw] = "retw",
1091 [JRetl] = "retl",1091 [Jretl] = "retl",
1092 [JRetc] = "retc",1092 [Jretc] = "retc",
1093 [JRets] = "rets",1093 [Jrets] = "rets",
1094 [JRetd] = "retd",1094 [Jretd] = "retd",
1095 [JJnz] = "jnz",1095 [Jjnz] = "jnz",
1096 [JXJnp] = "xjnp",1096 [Jxjnp] = "xjnp",
1097 [JXJp] = "xjp",1097 [Jxjp] = "xjp",
1098 #define X(c) [JXJc+IC##c] = "xj" #c,1098 #define X(c) [Jxjc+IC##c] = "xj" #c,
1099 ICMPS(X)1099 ICMPS(X)
1100 #undef X1100 #undef X
1101 };1101 };
1102 static char prcls[NOp] = {1102 static char prcls[NOp] = {
1103 [OArg] = 1,1103 [Oarg] = 1,
1104 [OSwap] = 1,1104 [Oswap] = 1,
1105 [OXCmp] = 1,1105 [Oxcmp] = 1,
1106 [OXTest] = 1,1106 [Oxtest] = 1,
1107 [OXDiv] = 1,1107 [Oxdiv] = 1,
1108 [OXIDiv] = 1,1108 [Oxidiv] = 1,
1109 };1109 };
1110 static char ktoc[] = "wlsd";1110 static char ktoc[] = "wlsd";
1111 Blk *b;1111 Blk *b;
@@ -1154,28 +1154,28 @@ printfn(Fn *fn, FILE *f) · 42 unmodified lines
1154 fprintf(f, "\n");1154 fprintf(f, "\n");
1155 }1155 }
1156 switch (b->jmp.type) {1156 switch (b->jmp.type) {
1157 case JRet0:1157 case Jret0:
1158 case JRetw:1158 case Jretw:
1159 case JRetl:1159 case Jretl:
1160 case JRets:1160 case Jrets:
1161 case JRetd:1161 case Jretd:
1162 case JRetc:1162 case Jretc:
1163 fprintf(f, "\t%s", jtoa[b->jmp.type]);1163 fprintf(f, "\t%s", jtoa[b->jmp.type]);
1164 if (b->jmp.type != JRet0 || !req(b->jmp.arg, R)) {1164 if (b->jmp.type != Jret0 || !req(b->jmp.arg, R)) {
1165 fprintf(f, " ");1165 fprintf(f, " ");
1166 printref(b->jmp.arg, fn, f);1166 printref(b->jmp.arg, fn, f);
1167 }1167 }
1168 if (b->jmp.type == JRetc)1168 if (b->jmp.type == Jretc)
1169 fprintf(f, ", :%s", typ[fn->retty].name);1169 fprintf(f, ", :%s", typ[fn->retty].name);
1170 fprintf(f, "\n");1170 fprintf(f, "\n");
1171 break;1171 break;
1172 case JJmp:1172 case Jjmp:
1173 if (b->s1 != b->link)1173 if (b->s1 != b->link)
1174 fprintf(f, "\tjmp @%s\n", b->s1->name);1174 fprintf(f, "\tjmp @%s\n", b->s1->name);
1175 break;1175 break;
1176 default:1176 default:
1177 fprintf(f, "\t%s ", jtoa[b->jmp.type]);1177 fprintf(f, "\t%s ", jtoa[b->jmp.type]);
1178 if (b->jmp.type == JJnz) {1178 if (b->jmp.type == Jjnz) {
1179 printref(b->jmp.arg, fn, f);1179 printref(b->jmp.arg, fn, f);
1180 fprintf(f, ", ");1180 fprintf(f, ", ");
1181 }1181 }
rega.c+10−10
@@ -224,10 +224,10 @@ pmrec(enum PMStat *status, int i, int *k) · 223 unmodified lines
224 }224 }
225 status[i] = Moved;225 status[i] = Moved;
226 if (req(swp, R)) {226 if (req(swp, R)) {
227 *curi++ = (Ins){OCopy, pm[i].dst, {pm[i].src}, pm[i].cls};227 *curi++ = (Ins){Ocopy, pm[i].dst, {pm[i].src}, pm[i].cls};
228 return R;228 return R;
229 } else if (!req(swp, pm[i].src)) {229 } else if (!req(swp, pm[i].src)) {
230 *curi++ = (Ins){OSwap, R, {pm[i].src, pm[i].dst}, *k};230 *curi++ = (Ins){Oswap, R, {pm[i].src, pm[i].dst}, *k};
231 return swp;231 return swp;
232 } else232 } else
233 return R;233 return R;
@@ -273,7 +273,7 @@ move(int r, Ref to, RMap *m) · 39 unmodified lines
273static int273static int
274regcpy(Ins *i)274regcpy(Ins *i)
275{275{
276 return i->op == OCopy && isreg(i->arg[0]);276 return i->op == Ocopy && isreg(i->arg[0]);
277}277}
278 278
279static Ins *279static Ins *
@@ -291,7 +291,7 @@ dopm(Blk *b, Ins *i, RMap *m) · 11 unmodified lines
291 move(i->arg[0].val, i->to, m);291 move(i->arg[0].val, i->to, m);
292 } while (i != b->ins && regcpy(i-1));292 } while (i != b->ins && regcpy(i-1));
293 assert(m0.n <= m->n);293 assert(m0.n <= m->n);
294 if (i != b->ins && (i-1)->op == OCall) {294 if (i != b->ins && (i-1)->op == Ocall) {
295 def = retregs((i-1)->arg[1], 0);295 def = retregs((i-1)->arg[1], 0);
296 for (r=0; r<NRSave; r++)296 for (r=0; r<NRSave; r++)
297 if (!(BIT(rsave[r]) & def))297 if (!(BIT(rsave[r]) & def))
@@ -371,13 +371,13 @@ doblk(Blk *b, RMap *cur) · 73 unmodified lines
371 }371 }
372 for (i=&b->ins[b->nins]; i!=b->ins;) {372 for (i=&b->ins[b->nins]; i!=b->ins;) {
373 switch ((--i)->op) {373 switch ((--i)->op) {
374 case OCall:374 case Ocall:
375 rs = argregs(i->arg[1], 0);375 rs = argregs(i->arg[1], 0);
376 for (r=0; r<NRSave; r++)376 for (r=0; r<NRSave; r++)
377 if (!(BIT(rsave[r]) & rs))377 if (!(BIT(rsave[r]) & rs))
378 rfree(cur, rsave[r]);378 rfree(cur, rsave[r]);
379 break;379 break;
380 case OCopy:380 case Ocopy:
381 if (isreg(i->arg[0])) {381 if (isreg(i->arg[0])) {
382 i = dopm(b, i, cur);382 i = dopm(b, i, cur);
383 continue;383 continue;
@@ -391,7 +391,7 @@ doblk(Blk *b, RMap *cur) · 7 unmodified lines
391 assert(rtype(i->to) == RTmp);391 assert(rtype(i->to) == RTmp);
392 r = rfree(cur, i->to.val);392 r = rfree(cur, i->to.val);
393 if (r == -1 && !isreg(i->to)) {393 if (r == -1 && !isreg(i->to)) {
394 *i = (Ins){.op = ONop};394 *i = (Ins){.op = Onop};
395 continue;395 continue;
396 }396 }
397 if (i->to.val >= Tmp0)397 if (i->to.val >= Tmp0)
@@ -447,7 +447,7 @@ rega(Fn *fn) · 49 unmodified lines
447 for (t=Tmp0; t<fn->ntmp; t++)447 for (t=Tmp0; t<fn->ntmp; t++)
448 *hint(t) = -1;448 *hint(t) = -1;
449 for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)449 for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)
450 if (i->op != OCopy || !isreg(i->arg[0]))450 if (i->op != Ocopy || !isreg(i->arg[0]))
451 break;451 break;
452 else {452 else {
453 assert(rtype(i->to) == RTmp);453 assert(rtype(i->to) == RTmp);
@@ -507,7 +507,7 @@ rega(Fn *fn) · 53 unmodified lines
507 rfree(&cur, t);507 rfree(&cur, t);
508 radd(&cur, t, r);508 radd(&cur, t, r);
509 x = tmp[t].cls;509 x = tmp[t].cls;
510 emit(OCopy, x, TMP(r1), TMP(r), R);510 emit(Ocopy, x, TMP(r1), TMP(r), R);
511 }511 }
512 }512 }
513 if ((j = &insb[NIns] - curi)) {513 if ((j = &insb[NIns] - curi)) {
@@ -569,7 +569,7 @@ rega(Fn *fn) · 55 unmodified lines
569 sprintf(b1->name, "%s_%s", b->name, s->name);569 sprintf(b1->name, "%s_%s", b->name, s->name);
570 b1->nins = curi - insb;570 b1->nins = curi - insb;
571 idup(&b1->ins, insb, b1->nins);571 idup(&b1->ins, insb, b1->nins);
572 b1->jmp.type = JJmp;572 b1->jmp.type = Jjmp;
573 b1->s1 = s;573 b1->s1 = s;
574 **ps = b1;574 **ps = b1;
575 }575 }
spill.c+5−5
@@ -234,20 +234,20 @@ reloads(BSet *u, BSet *v) · 233 unmodified lines
234 234
235 for (t=Tmp0; bsiter(u, &t); t++)235 for (t=Tmp0; bsiter(u, &t); t++)
236 if (!bshas(v, t))236 if (!bshas(v, t))
237 emit(OLoad, tmp[t].cls, TMP(t), slot(t), R);237 emit(Oload, tmp[t].cls, TMP(t), slot(t), R);
238}238}
239 239
240static void240static void
241store(Ref r, int s)241store(Ref r, int s)
242{242{
243 if (s != -1)243 if (s != -1)
244 emit(OStorew + tmp[r.val].cls, 0, R, r, SLOT(s));244 emit(Ostorew + tmp[r.val].cls, 0, R, r, SLOT(s));
245}245}
246 246
247static int247static int
248regcpy(Ins *i)248regcpy(Ins *i)
249{249{
250 return i->op == OCopy && isreg(i->arg[0]);250 return i->op == Ocopy && isreg(i->arg[0]);
251}251}
252 252
253static Ins *253static Ins *
@@ -281,7 +281,7 @@ dopm(Blk *b, Ins *i, BSet *v) · 27 unmodified lines
281 bsset(v, i->arg[0].val);281 bsset(v, i->arg[0].val);
282 } while (i != b->ins && regcpy(i-1));282 } while (i != b->ins && regcpy(i-1));
283 bscopy(u, v);283 bscopy(u, v);
284 if (i != b->ins && (i-1)->op == OCall) {284 if (i != b->ins && (i-1)->op == Ocall) {
285 v->t[0] &= ~retregs((i-1)->arg[1], 0);285 v->t[0] &= ~retregs((i-1)->arg[1], 0);
286 limit2(v, NISave, NFSave, 0);286 limit2(v, NISave, NFSave, 0);
287 for (r=0, n=0; n<NRSave; n++)287 for (r=0, n=0; n<NRSave; n++)
@@ -308,7 +308,7 @@ dopm(Blk *b, Ins *i, BSet *v) · 20 unmodified lines
308 * borders308 * borders
309 *309 *
310 * Be careful with:310 * Be careful with:
311 * - OCopy instructions to ensure register311 * - Ocopy instructions to ensure register
312 * constraints312 * constraints
313 */313 */
314void314void
sysv.c+56−56
@@ -76,11 +76,11 @@ blit(Ref rstk, uint soff, Ref rsrc, uint sz, Fn *fn) · 75 unmodified lines
76 for (boff=0; sz>0; sz-=8, soff+=8, boff+=8) {76 for (boff=0; sz>0; sz-=8, soff+=8, boff+=8) {
77 r = newtmp("abi", Kl, fn);77 r = newtmp("abi", Kl, fn);
78 r1 = newtmp("abi", Kl, fn);78 r1 = newtmp("abi", Kl, fn);
79 emit(OStorel, 0, R, r, r1);79 emit(Ostorel, 0, R, r, r1);
80 emit(OAdd, Kl, r1, rstk, getcon(soff, fn));80 emit(Oadd, Kl, r1, rstk, getcon(soff, fn));
81 r1 = newtmp("abi", Kl, fn);81 r1 = newtmp("abi", Kl, fn);
82 emit(OLoad, Kl, r, r1, R);82 emit(Oload, Kl, r, r1, R);
83 emit(OAdd, Kl, r1, rsrc, getcon(boff, fn));83 emit(Oadd, Kl, r1, rsrc, getcon(boff, fn));
84 }84 }
85}85}
86 86
@@ -109,35 +109,35 @@ selret(Blk *b, Fn *fn) · 22 unmodified lines
109 109
110 j = b->jmp.type;110 j = b->jmp.type;
111 111
112 if (!isret(j) || j == JRet0)112 if (!isret(j) || j == Jret0)
113 return;113 return;
114 114
115 r0 = b->jmp.arg;115 r0 = b->jmp.arg;
116 b->jmp.type = JRet0;116 b->jmp.type = Jret0;
117 117
118 if (j == JRetc) {118 if (j == Jretc) {
119 aclass(&aret, &typ[fn->retty]);119 aclass(&aret, &typ[fn->retty]);
120 if (aret.inmem) {120 if (aret.inmem) {
121 assert(rtype(fn->retr) == RTmp);121 assert(rtype(fn->retr) == RTmp);
122 emit(OCopy, Kl, TMP(RAX), fn->retr, R);122 emit(Ocopy, Kl, TMP(RAX), fn->retr, R);
123 blit(fn->retr, 0, r0, aret.size, fn);123 blit(fn->retr, 0, r0, aret.size, fn);
124 ca = 1;124 ca = 1;
125 } else {125 } else {
126 ca = retr(reg, &aret);126 ca = retr(reg, &aret);
127 if (aret.size > 8) {127 if (aret.size > 8) {
128 r = newtmp("abi", Kl, fn);128 r = newtmp("abi", Kl, fn);
129 emit(OLoad, Kl, reg[1], r, R);129 emit(Oload, Kl, reg[1], r, R);
130 emit(OAdd, Kl, r, r0, getcon(8, fn));130 emit(Oadd, Kl, r, r0, getcon(8, fn));
131 }131 }
132 emit(OLoad, Kl, reg[0], r0, R);132 emit(Oload, Kl, reg[0], r0, R);
133 }133 }
134 } else {134 } else {
135 k = j - JRetw;135 k = j - Jretw;
136 if (KBASE(k) == 0) {136 if (KBASE(k) == 0) {
137 emit(OCopy, k, TMP(RAX), r0, R);137 emit(Ocopy, k, TMP(RAX), r0, R);
138 ca = 1;138 ca = 1;
139 } else {139 } else {
140 emit(OCopy, k, TMP(XMM0), r0, R);140 emit(Ocopy, k, TMP(XMM0), r0, R);
141 ca = 1 << 2;141 ca = 1 << 2;
142 }142 }
143 }143 }
@@ -272,9 +272,9 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap) · 128 unmodified lines
272 if (!req(i1->arg[1], R)) {272 if (!req(i1->arg[1], R)) {
273 assert(rtype(i1->arg[1]) == RType);273 assert(rtype(i1->arg[1]) == RType);
274 aclass(&aret, &typ[i1->arg[1].val]);274 aclass(&aret, &typ[i1->arg[1].val]);
275 ca = classify(i0, i1, ac, OArg, &aret);275 ca = classify(i0, i1, ac, Oarg, &aret);
276 } else276 } else
277 ca = classify(i0, i1, ac, OArg, 0);277 ca = classify(i0, i1, ac, Oarg, 0);
278 278
279 for (stk=0, a=&ac[i1-i0]; a>ac;)279 for (stk=0, a=&ac[i1-i0]; a>ac;)
280 if ((--a)->inmem) {280 if ((--a)->inmem) {
@@ -287,7 +287,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap) · 6 unmodified lines
287 stk += stk & 15;287 stk += stk & 15;
288 if (stk) {288 if (stk) {
289 r = getcon(-(int64_t)stk, fn);289 r = getcon(-(int64_t)stk, fn);
290 emit(OSAlloc, Kl, R, r, R);290 emit(Osalloc, Kl, R, r, R);
291 }291 }
292 292
293 if (!req(i1->arg[1], R)) {293 if (!req(i1->arg[1], R)) {
@@ -295,60 +295,60 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap) · 1 unmodified line
295 /* get the return location from eax295 /* get the return location from eax
296 * it saves one callee-save reg */296 * it saves one callee-save reg */
297 r1 = newtmp("abi", Kl, fn);297 r1 = newtmp("abi", Kl, fn);
298 emit(OCopy, Kl, i1->to, TMP(RAX), R);298 emit(Ocopy, Kl, i1->to, TMP(RAX), R);
299 ca += 1;299 ca += 1;
300 } else {300 } else {
301 if (aret.size > 8) {301 if (aret.size > 8) {
302 r = newtmp("abi", Kl, fn);302 r = newtmp("abi", Kl, fn);
303 aret.ref[1] = newtmp("abi", aret.cls[1], fn);303 aret.ref[1] = newtmp("abi", aret.cls[1], fn);
304 emit(OStorel, 0, R, aret.ref[1], r);304 emit(Ostorel, 0, R, aret.ref[1], r);
305 emit(OAdd, Kl, r, i1->to, getcon(8, fn));305 emit(Oadd, Kl, r, i1->to, getcon(8, fn));
306 }306 }
307 aret.ref[0] = newtmp("abi", aret.cls[0], fn);307 aret.ref[0] = newtmp("abi", aret.cls[0], fn);
308 emit(OStorel, 0, R, aret.ref[0], i1->to);308 emit(Ostorel, 0, R, aret.ref[0], i1->to);
309 ca += retr(reg, &aret);309 ca += retr(reg, &aret);
310 if (aret.size > 8)310 if (aret.size > 8)
311 emit(OCopy, aret.cls[1], aret.ref[1], reg[1], R);311 emit(Ocopy, aret.cls[1], aret.ref[1], reg[1], R);
312 emit(OCopy, aret.cls[0], aret.ref[0], reg[0], R);312 emit(Ocopy, aret.cls[0], aret.ref[0], reg[0], R);
313 r1 = i1->to;313 r1 = i1->to;
314 }314 }
315 /* allocate return pad */315 /* allocate return pad */
316 ra = alloc(sizeof *ra);316 ra = alloc(sizeof *ra);
317 /* specific to NAlign == 3 */317 /* specific to NAlign == 3 */
318 al = aret.align >= 2 ? aret.align - 2 : 0;318 al = aret.align >= 2 ? aret.align - 2 : 0;
319 ra->i = (Ins){OAlloc+al, r1, {getcon(aret.size, fn)}, Kl};319 ra->i = (Ins){Oalloc+al, r1, {getcon(aret.size, fn)}, Kl};
320 ra->link = (*rap);320 ra->link = (*rap);
321 *rap = ra;321 *rap = ra;
322 } else {322 } else {
323 ra = 0;323 ra = 0;
324 if (KBASE(i1->cls) == 0) {324 if (KBASE(i1->cls) == 0) {
325 emit(OCopy, i1->cls, i1->to, TMP(RAX), R);325 emit(Ocopy, i1->cls, i1->to, TMP(RAX), R);
326 ca += 1;326 ca += 1;
327 } else {327 } else {
328 emit(OCopy, i1->cls, i1->to, TMP(XMM0), R);328 emit(Ocopy, i1->cls, i1->to, TMP(XMM0), R);
329 ca += 1 << 2;329 ca += 1 << 2;
330 }330 }
331 }331 }
332 emit(OCall, i1->cls, R, i1->arg[0], CALL(ca));332 emit(Ocall, i1->cls, R, i1->arg[0], CALL(ca));
333 emit(OCopy, Kw, TMP(RAX), getcon((ca >> 8) & 15, fn), R);333 emit(Ocopy, Kw, TMP(RAX), getcon((ca >> 8) & 15, fn), R);
334 334
335 ni = ns = 0;335 ni = ns = 0;
336 if (ra && aret.inmem)336 if (ra && aret.inmem)
337 emit(OCopy, Kl, rarg(Kl, &ni, &ns), ra->i.to, R); /* pass hidden argument */337 emit(Ocopy, Kl, rarg(Kl, &ni, &ns), ra->i.to, R); /* pass hidden argument */
338 for (i=i0, a=ac; i<i1; i++, a++) {338 for (i=i0, a=ac; i<i1; i++, a++) {
339 if (a->inmem)339 if (a->inmem)
340 continue;340 continue;
341 r1 = rarg(a->cls[0], &ni, &ns);341 r1 = rarg(a->cls[0], &ni, &ns);
342 if (i->op == OArgc) {342 if (i->op == Oargc) {
343 if (a->size > 8) {343 if (a->size > 8) {
344 r2 = rarg(a->cls[1], &ni, &ns);344 r2 = rarg(a->cls[1], &ni, &ns);
345 r = newtmp("abi", Kl, fn);345 r = newtmp("abi", Kl, fn);
346 emit(OLoad, a->cls[1], r2, r, R);346 emit(Oload, a->cls[1], r2, r, R);
347 emit(OAdd, Kl, r, i->arg[1], getcon(8, fn));347 emit(Oadd, Kl, r, i->arg[1], getcon(8, fn));
348 }348 }
349 emit(OLoad, a->cls[0], r1, i->arg[1], R);349 emit(Oload, a->cls[0], r1, i->arg[1], R);
350 } else350 } else
351 emit(OCopy, i->cls, r1, i->arg[0], R);351 emit(Ocopy, i->cls, r1, i->arg[0], R);
352 }352 }
353 353
354 if (!stk)354 if (!stk)
@@ -358,18 +358,18 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap) · 3 unmodified lines
358 for (i=i0, a=ac, off=0; i<i1; i++, a++) {358 for (i=i0, a=ac, off=0; i<i1; i++, a++) {
359 if (!a->inmem)359 if (!a->inmem)
360 continue;360 continue;
361 if (i->op == OArgc) {361 if (i->op == Oargc) {
362 if (a->align == 4)362 if (a->align == 4)
363 off += off & 15;363 off += off & 15;
364 blit(r, off, i->arg[1], a->size, fn);364 blit(r, off, i->arg[1], a->size, fn);
365 } else {365 } else {
366 r1 = newtmp("abi", Kl, fn);366 r1 = newtmp("abi", Kl, fn);
367 emit(OStorel, 0, R, i->arg[0], r1);367 emit(Ostorel, 0, R, i->arg[0], r1);
368 emit(OAdd, Kl, r1, r, getcon(off, fn));368 emit(Oadd, Kl, r1, r, getcon(off, fn));
369 }369 }
370 off += a->size;370 off += a->size;
371 }371 }
372 emit(OSAlloc, Kl, r, getcon(stk, fn), R);372 emit(Osalloc, Kl, r, getcon(stk, fn), R);
373}373}
374 374
375static void375static void
@@ -386,29 +386,29 @@ selpar(Fn *fn, Ins *i0, Ins *i1) · 10 unmodified lines
386 386
387 if (fn->retty >= 0) {387 if (fn->retty >= 0) {
388 aclass(&aret, &typ[fn->retty]);388 aclass(&aret, &typ[fn->retty]);
389 classify(i0, i1, ac, OPar, &aret);389 classify(i0, i1, ac, Opar, &aret);
390 } else390 } else
391 classify(i0, i1, ac, OPar, 0);391 classify(i0, i1, ac, Opar, 0);
392 392
393 for (i=i0, a=ac; i<i1; i++, a++) {393 for (i=i0, a=ac; i<i1; i++, a++) {
394 if (i->op != OParc || a->inmem)394 if (i->op != Oparc || a->inmem)
395 continue;395 continue;
396 if (a->size > 8) {396 if (a->size > 8) {
397 r = newtmp("abi", Kl, fn);397 r = newtmp("abi", Kl, fn);
398 a->ref[1] = newtmp("abi", Kl, fn);398 a->ref[1] = newtmp("abi", Kl, fn);
399 emit(OStorel, 0, R, a->ref[1], r);399 emit(Ostorel, 0, R, a->ref[1], r);
400 emit(OAdd, Kl, r, i->to, getcon(8, fn));400 emit(Oadd, Kl, r, i->to, getcon(8, fn));
401 }401 }
402 a->ref[0] = newtmp("abi", Kl, fn);402 a->ref[0] = newtmp("abi", Kl, fn);
403 emit(OStorel, 0, R, a->ref[0], i->to);403 emit(Ostorel, 0, R, a->ref[0], i->to);
404 /* specific to NAlign == 3 */404 /* specific to NAlign == 3 */
405 al = a->align >= 2 ? a->align - 2 : 0;405 al = a->align >= 2 ? a->align - 2 : 0;
406 emit(OAlloc+al, Kl, i->to, getcon(a->size, fn), R);406 emit(Oalloc+al, Kl, i->to, getcon(a->size, fn), R);
407 }407 }
408 408
409 if (fn->retty >= 0 && aret.inmem) {409 if (fn->retty >= 0 && aret.inmem) {
410 r = newtmp("abi", Kl, fn);410 r = newtmp("abi", Kl, fn);
411 emit(OCopy, Kl, r, rarg(Kl, &ni, &ns), R);411 emit(Ocopy, Kl, r, rarg(Kl, &ni, &ns), R);
412 fn->retr = r;412 fn->retr = r;
413 }413 }
414 414
@@ -423,19 +423,19 @@ selpar(Fn *fn, Ins *i0, Ins *i1) · 8 unmodified lines
423 s += a->size / 4;423 s += a->size / 4;
424 continue;424 continue;
425 case 2:425 case 2:
426 emit(OLoad, i->cls, i->to, SLOT(-s), R);426 emit(Oload, i->cls, i->to, SLOT(-s), R);
427 s += 2;427 s += 2;
428 continue;428 continue;
429 }429 }
430 r = rarg(a->cls[0], &ni, &ns);430 r = rarg(a->cls[0], &ni, &ns);
431 if (i->op == OParc) {431 if (i->op == Oparc) {
432 emit(OCopy, Kl, a->ref[0], r, R);432 emit(Ocopy, Kl, a->ref[0], r, R);
433 if (a->size > 8) {433 if (a->size > 8) {
434 r = rarg(a->cls[1], &ni, &ns);434 r = rarg(a->cls[1], &ni, &ns);
435 emit(OCopy, Kl, a->ref[1], r, R);435 emit(Ocopy, Kl, a->ref[1], r, R);
436 }436 }
437 } else437 } else
438 emit(OCopy, i->cls, i->to, r, R);438 emit(Ocopy, i->cls, i->to, r, R);
439 }439 }
440}440}
441 441
@@ -449,7 +449,7 @@ abi(Fn *fn) · 7 unmodified lines
449 449
450 /* lower arguments */450 /* lower arguments */
451 for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)451 for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)
452 if (i->op != OPar && i->op != OParc)452 if (i->op != Opar && i->op != Oparc)
453 break;453 break;
454 selpar(fn, b->ins, i);454 selpar(fn, b->ins, i);
455 n = b->nins - (i - b->ins) + (&insb[NIns] - curi);455 n = b->nins - (i - b->ins) + (&insb[NIns] - curi);
@@ -468,16 +468,16 @@ abi(Fn *fn) · 12 unmodified lines
468 curi = &insb[NIns];468 curi = &insb[NIns];
469 selret(b, fn);469 selret(b, fn);
470 for (i=&b->ins[b->nins]; i!=b->ins;) {470 for (i=&b->ins[b->nins]; i!=b->ins;) {
471 if ((--i)->op == OCall) {471 if ((--i)->op == Ocall) {
472 for (i0=i; i0>b->ins; i0--)472 for (i0=i; i0>b->ins; i0--)
473 if ((i0-1)->op != OArg)473 if ((i0-1)->op != Oarg)
474 if ((i0-1)->op != OArgc)474 if ((i0-1)->op != Oargc)
475 break;475 break;
476 selcall(fn, i0, i, &ral);476 selcall(fn, i0, i, &ral);
477 i = i0;477 i = i0;
478 continue;478 continue;
479 }479 }
480 assert(i->op != OArg && i->op != OArgc);480 assert(i->op != Oarg && i->op != Oargc);
481 emiti(*i);481 emiti(*i);
482 }482 }
483 if (b == fn->start)483 if (b == fn->start)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t