Unified · Split
| @@ -162,8 +162,8 @@ enum ICmp { · 161 unmodified lines | |||
| 162 | #undef X | 162 | #undef X |
| 163 | NICmp, | 163 | NICmp, |
| 164 | 164 | ||
| 165 | ICXnp = NICmp, /* x64 specific */ | 165 | ICxnp = NICmp, /* x64 specific */ |
| 166 | ICXp, | 166 | ICxp, |
| 167 | NXICmp | 167 | 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 | ||
| 203 | enum Op { | 203 | enum 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 | NOp | 284 | NOp |
| 285 | }; | 285 | }; |
| 286 | 286 | ||
| 287 | enum Jmp { | 287 | enum 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 | NJmp | 301 | NJmp |
| 302 | }; | 302 | }; |
| 303 | 303 | ||
| @@ -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++) |
| @@ -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 inserted | 368 | /* 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 form | 372 | /* 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 handle | 387 | /* 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-bits | 397 | * also, we can use a trick to load 64-bits |
| 398 | * registers, it's detailed in my note below | 398 | * 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&T | 417 | /* 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 here | 433 | /* there is no good reason why this is here |
| 434 | * maybe we should split OSAlloc in 2 different | 434 | * maybe we should split Osalloc in 2 different |
| 435 | * instructions depending on the result | 435 | * 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 instruction | 444 | /* 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; |
| @@ -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 != JJmp | 229 | assert(b->jmp.type != Jjmp |
| 230 | || !edge[n][0].dead | 230 | || !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 | else | 294 | 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 | else | 380 | 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 | } else | 393 | } 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 == OUDiv | 489 | 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); |
| @@ -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 | else | 69 | else |
| @@ -141,7 +141,7 @@ fixarg(Ref *r, int k, int phi, Fn *fn) · 71 unmodified lines | |||
| 141 | * long temporary | 141 | * 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 into | 147 | /* load fast locals' addresses into |
| @@ -149,7 +149,7 @@ fixarg(Ref *r, int k, int phi, Fn *fn) · 1 unmodified line | |||
| 149 | * instruction | 149 | * 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 | else | 223 | 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 for | 228 | /* immediates not allowed for |
| 229 | * divisions in x86 | 229 | * 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: |
| 295 | Emit: | 295 | Emit: |
| 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 sure | 304 | /* we need to make sure |
| 305 | * the stack remains aligned | 305 | * the stack remains aligned |
| 306 | * (rsp = 0) mod 16 | 306 | * (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 == 1 | 392 | 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 live | 407 | * 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 | ||
| 418 | static int | 418 | static 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 */ |
| @@ -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]; |
| @@ -4,10 +4,10 @@ static int · 3 unmodified lines | |||
| 4 | loadsz(Ins *l) | 4 | loadsz(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 | |||
| 16 | storesz(Ins *s) | 16 | storesz(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 we | 86 | /* 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 | else | 94 | 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 | } |
| @@ -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 X | 76 | #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 X | 81 | #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 | else | 457 | else |
| 458 | *curi = (Ins){OParc, r, {TYPE(ty)}, Kl}; | 458 | *curi = (Ins){Oparc, r, {TYPE(ty)}, Kl}; |
| 459 | else | 459 | else |
| 460 | if (arg) | 460 | if (arg) |
| 461 | *curi = (Ins){OArg, R, {r}, k}; | 461 | *curi = (Ins){Oarg, R, {r}, k}; |
| 462 | else | 462 | 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, JRet0 | 541 | 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 | |||
| 1086 | printfn(Fn *fn, FILE *f) | 1086 | printfn(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 X | 1100 | #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 | } |
| @@ -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 | } else | 232 | } else |
| 233 | return R; | 233 | return R; |
| @@ -273,7 +273,7 @@ move(int r, Ref to, RMap *m) · 39 unmodified lines | |||
| 273 | static int | 273 | static int |
| 274 | regcpy(Ins *i) | 274 | regcpy(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 | ||
| 279 | static Ins * | 279 | static 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 | } |
| @@ -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 | ||
| 240 | static void | 240 | static void |
| 241 | store(Ref r, int s) | 241 | store(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 | ||
| 247 | static int | 247 | static int |
| 248 | regcpy(Ins *i) | 248 | regcpy(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 | ||
| 253 | static Ins * | 253 | static 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 | * borders | 308 | * borders |
| 309 | * | 309 | * |
| 310 | * Be careful with: | 310 | * Be careful with: |
| 311 | * - OCopy instructions to ensure register | 311 | * - Ocopy instructions to ensure register |
| 312 | * constraints | 312 | * constraints |
| 313 | */ | 313 | */ |
| 314 | void | 314 | void |
| @@ -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 | } else | 276 | } 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 eax | 295 | /* 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 | } else | 350 | } 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 | ||
| 375 | static void | 375 | static 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 | } else | 390 | } 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 | } else | 437 | } 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) |