It is more natural to branch on a flag than have different function pointers for high-level passes.
Unified · Split
| @@ -41,6 +41,7 @@ enum { · 40 unmodified lines | |||
| 41 | 41 | ||
| 42 | struct Target { | 42 | struct Target { |
| 43 | char name[16]; | 43 | char name[16]; |
| 44 | char apple; | ||
| 44 | int gpr0; /* first general purpose reg */ | 45 | int gpr0; /* first general purpose reg */ |
| 45 | int ngpr; | 46 | int ngpr; |
| 46 | int fpr0; /* first floating point reg */ | 47 | int fpr0; /* first floating point reg */ |
| @@ -67,5 +67,4 @@ void amd64_sysv_abi(Fn *); · 66 unmodified lines | |||
| 67 | void amd64_isel(Fn *); | 67 | void amd64_isel(Fn *); |
| 68 | 68 | ||
| 69 | /* emit.c */ | 69 | /* emit.c */ |
| 70 | void amd64_sysv_emitfn(Fn *, FILE *); | 70 | void amd64_emitfn(Fn *, FILE *); |
| 71 | void amd64_apple_emitfn(Fn *, FILE *); | ||
| @@ -538,8 +538,8 @@ framesz(Fn *fn) · 537 unmodified lines | |||
| 538 | return 4*f + 8*o + 176*fn->vararg; | 538 | return 4*f + 8*o + 176*fn->vararg; |
| 539 | } | 539 | } |
| 540 | 540 | ||
| 541 | static void | 541 | void |
| 542 | emitfn(Fn *fn, FILE *f) | 542 | amd64_emitfn(Fn *fn, FILE *f) |
| 543 | { | 543 | { |
| 544 | static char *ctoa[] = { | 544 | static char *ctoa[] = { |
| 545 | #define X(c, s) [c] = s, | 545 | #define X(c, s) [c] = s, |
| @@ -620,17 +620,6 @@ emitfn(Fn *fn, FILE *f) · 74 unmodified lines | |||
| 620 | } | 620 | } |
| 621 | } | 621 | } |
| 622 | id0 += fn->nblk; | 622 | id0 += fn->nblk; |
| 623 | } | 623 | if (!T.apple) |
| 624 | 624 | elf_emitfnfin(fn->name, f); | |
| 625 | void | ||
| 626 | amd64_sysv_emitfn(Fn *fn, FILE *f) | ||
| 627 | { | ||
| 628 | emitfn(fn, f); | ||
| 629 | elf_emitfnfin(fn->name, f); | ||
| 630 | } | ||
| 631 | |||
| 632 | void | ||
| 633 | amd64_apple_emitfn(Fn *fn, FILE *f) | ||
| 634 | { | ||
| 635 | emitfn(fn, f); | ||
| 636 | } | 625 | } |
| @@ -27,10 +27,10 @@ amd64_memargs(int op) · 26 unmodified lines | |||
| 27 | .abi0 = elimsb, \ | 27 | .abi0 = elimsb, \ |
| 28 | .abi1 = amd64_sysv_abi, \ | 28 | .abi1 = amd64_sysv_abi, \ |
| 29 | .isel = amd64_isel, \ | 29 | .isel = amd64_isel, \ |
| 30 | .emitfn = amd64_emitfn, \ | ||
| 30 | 31 | ||
| 31 | Target T_amd64_sysv = { | 32 | Target T_amd64_sysv = { |
| 32 | .name = "amd64_sysv", | 33 | .name = "amd64_sysv", |
| 33 | .emitfn = amd64_sysv_emitfn, | ||
| 34 | .emitfin = elf_emitfin, | 34 | .emitfin = elf_emitfin, |
| 35 | .asloc = ".L", | 35 | .asloc = ".L", |
| 36 | AMD64_COMMON | 36 | AMD64_COMMON |
| @@ -38,7 +38,7 @@ Target T_amd64_sysv = { · 1 unmodified line | |||
| 38 | 38 | ||
| 39 | Target T_amd64_apple = { | 39 | Target T_amd64_apple = { |
| 40 | .name = "amd64_apple", | 40 | .name = "amd64_apple", |
| 41 | .emitfn = amd64_apple_emitfn, | 41 | .apple = 1, |
| 42 | .emitfin = macho_emitfin, | 42 | .emitfin = macho_emitfin, |
| 43 | .asloc = "L", | 43 | .asloc = "L", |
| 44 | .assym = "_", | 44 | .assym = "_", |
| @@ -10,12 +10,6 @@ enum { · 9 unmodified lines | |||
| 10 | Cptr = 2, /* replaced by a pointer */ | 10 | Cptr = 2, /* replaced by a pointer */ |
| 11 | }; | 11 | }; |
| 12 | 12 | ||
| 13 | struct Abi { | ||
| 14 | void (*vastart)(Fn *, Params, Ref); | ||
| 15 | void (*vaarg)(Fn *, Blk *, Ins *); | ||
| 16 | int apple; | ||
| 17 | }; | ||
| 18 | |||
| 19 | struct Class { | 13 | struct Class { |
| 20 | char class; | 14 | char class; |
| 21 | char ishfa; | 15 | char ishfa; |
| @@ -215,7 +209,7 @@ selret(Blk *b, Fn *fn) · 193 unmodified lines | |||
| 215 | } | 209 | } |
| 216 | 210 | ||
| 217 | static int | 211 | static int |
| 218 | argsclass(Ins *i0, Ins *i1, Class *carg, int apple) | 212 | argsclass(Ins *i0, Ins *i1, Class *carg) |
| 219 | { | 213 | { |
| 220 | int va, envc, ngp, nfp, *gp, *fp; | 214 | int va, envc, ngp, nfp, *gp, *fp; |
| 221 | Class *c; | 215 | Class *c; |
| @@ -244,7 +238,7 @@ argsclass(Ins *i0, Ins *i1, Class *carg, int apple) · 22 unmodified lines | |||
| 244 | case Opar: | 238 | case Opar: |
| 245 | case Oarg: | 239 | case Oarg: |
| 246 | c->size = 8; | 240 | c->size = 8; |
| 247 | if (apple && !KWIDE(i->cls)) | 241 | if (T.apple && !KWIDE(i->cls)) |
| 248 | c->size = 4; | 242 | c->size = 4; |
| 249 | Scalar: | 243 | Scalar: |
| 250 | c->align = c->size; | 244 | c->align = c->size; |
| @@ -290,7 +284,7 @@ argsclass(Ins *i0, Ins *i1, Class *carg, int apple) · 39 unmodified lines | |||
| 290 | envc = 1; | 284 | envc = 1; |
| 291 | break; | 285 | break; |
| 292 | case Oargv: | 286 | case Oargv: |
| 293 | va = apple != 0; | 287 | va = T.apple != 0; |
| 294 | break; | 288 | break; |
| 295 | default: | 289 | default: |
| 296 | die("unreachable"); | 290 | die("unreachable"); |
| @@ -367,7 +361,7 @@ align(uint x, uint al) · 70 unmodified lines | |||
| 367 | } | 361 | } |
| 368 | 362 | ||
| 369 | static void | 363 | static void |
| 370 | selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp, int apple) | 364 | selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp) |
| 371 | { | 365 | { |
| 372 | Ins *i; | 366 | Ins *i; |
| 373 | Class *ca, *c, cr; | 367 | Class *ca, *c, cr; |
| @@ -376,7 +370,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp, int apple) · 2 unmodified lines | |||
| 376 | Ref r, rstk, tmp[4]; | 370 | Ref r, rstk, tmp[4]; |
| 377 | 371 | ||
| 378 | ca = alloc((i1-i0) * sizeof ca[0]); | 372 | ca = alloc((i1-i0) * sizeof ca[0]); |
| 379 | cty = argsclass(i0, i1, ca, apple); | 373 | cty = argsclass(i0, i1, ca); |
| 380 | 374 | ||
| 381 | stk = 0; | 375 | stk = 0; |
| 382 | for (i=i0, c=ca; i<i1; i++, c++) { | 376 | for (i=i0, c=ca; i<i1; i++, c++) { |
| @@ -468,7 +462,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp, int apple) · 85 unmodified lines | |||
| 468 | } | 462 | } |
| 469 | 463 | ||
| 470 | static Params | 464 | static Params |
| 471 | selpar(Fn *fn, Ins *i0, Ins *i1, int apple) | 465 | selpar(Fn *fn, Ins *i0, Ins *i1) |
| 472 | { | 466 | { |
| 473 | Class *ca, *c, cr; | 467 | Class *ca, *c, cr; |
| 474 | Insl *il; | 468 | Insl *il; |
| @@ -480,7 +474,7 @@ selpar(Fn *fn, Ins *i0, Ins *i1, int apple) · 5 unmodified lines | |||
| 480 | ca = alloc((i1-i0) * sizeof ca[0]); | 474 | ca = alloc((i1-i0) * sizeof ca[0]); |
| 481 | curi = &insb[NIns]; | 475 | curi = &insb[NIns]; |
| 482 | 476 | ||
| 483 | cty = argsclass(i0, i1, ca, apple); | 477 | cty = argsclass(i0, i1, ca); |
| 484 | fn->reg = arm64_argregs(CALL(cty), 0); | 478 | fn->reg = arm64_argregs(CALL(cty), 0); |
| 485 | 479 | ||
| 486 | il = 0; | 480 | il = 0; |
| @@ -724,8 +718,8 @@ arm64_selvastart(Fn *fn, Params p, Ref ap) · 237 unmodified lines | |||
| 724 | emit(Oadd, Kl, r0, ap, getcon(28, fn)); | 718 | emit(Oadd, Kl, r0, ap, getcon(28, fn)); |
| 725 | } | 719 | } |
| 726 | 720 | ||
| 727 | static void | 721 | void |
| 728 | abi(Fn *fn, Abi abi) | 722 | arm64_abi(Fn *fn) |
| 729 | { | 723 | { |
| 730 | Blk *b; | 724 | Blk *b; |
| 731 | Ins *i, *i0, *ip; | 725 | Ins *i, *i0, *ip; |
| @@ -740,7 +734,7 @@ abi(Fn *fn, Abi abi) · 8 unmodified lines | |||
| 740 | for (b=fn->start, i=b->ins; i<&b->ins[b->nins]; i++) | 734 | for (b=fn->start, i=b->ins; i<&b->ins[b->nins]; i++) |
| 741 | if (!ispar(i->op)) | 735 | if (!ispar(i->op)) |
| 742 | break; | 736 | break; |
| 743 | p = selpar(fn, b->ins, i, abi.apple); | 737 | p = selpar(fn, b->ins, i); |
| 744 | n = b->nins - (i - b->ins) + (&insb[NIns] - curi); | 738 | n = b->nins - (i - b->ins) + (&insb[NIns] - curi); |
| 745 | i0 = alloc(n * sizeof(Ins)); | 739 | i0 = alloc(n * sizeof(Ins)); |
| 746 | ip = icpy(ip = i0, curi, &insb[NIns] - curi); | 740 | ip = icpy(ip = i0, curi, &insb[NIns] - curi); |
| @@ -767,14 +761,20 @@ abi(Fn *fn, Abi abi) · 20 unmodified lines | |||
| 767 | for (i0=i; i0>b->ins; i0--) | 761 | for (i0=i; i0>b->ins; i0--) |
| 768 | if (!isarg((i0-1)->op)) | 762 | if (!isarg((i0-1)->op)) |
| 769 | break; | 763 | break; |
| 770 | selcall(fn, i0, i, &il, abi.apple); | 764 | selcall(fn, i0, i, &il); |
| 771 | i = i0; | 765 | i = i0; |
| 772 | break; | 766 | break; |
| 773 | case Ovastart: | 767 | case Ovastart: |
| 774 | abi.vastart(fn, p, i->arg[0]); | 768 | if (T.apple) |
| 769 | apple_selvastart(fn, p, i->arg[0]); | ||
| 770 | else | ||
| 771 | arm64_selvastart(fn, p, i->arg[0]); | ||
| 775 | break; | 772 | break; |
| 776 | case Ovaarg: | 773 | case Ovaarg: |
| 777 | abi.vaarg(fn, b, i); | 774 | if (T.apple) |
| 775 | apple_selvaarg(fn, b, i); | ||
| 776 | else | ||
| 777 | arm64_selvaarg(fn, b, i); | ||
| 778 | break; | 778 | break; |
| 779 | case Oarg: | 779 | case Oarg: |
| 780 | case Oargc: | 780 | case Oargc: |
| @@ -793,26 +793,6 @@ abi(Fn *fn, Abi abi) · 12 unmodified lines | |||
| 793 | } | 793 | } |
| 794 | } | 794 | } |
| 795 | 795 | ||
| 796 | void | ||
| 797 | arm64_abi(Fn *fn) | ||
| 798 | { | ||
| 799 | abi(fn, (Abi){ | ||
| 800 | arm64_selvastart, | ||
| 801 | arm64_selvaarg, | ||
| 802 | 0 | ||
| 803 | }); | ||
| 804 | } | ||
| 805 | |||
| 806 | void | ||
| 807 | apple_abi(Fn *fn) | ||
| 808 | { | ||
| 809 | abi(fn, (Abi){ | ||
| 810 | apple_selvastart, | ||
| 811 | apple_selvaarg, | ||
| 812 | 1 | ||
| 813 | }); | ||
| 814 | } | ||
| 815 | |||
| 816 | /* abi0 for apple target; introduces | 796 | /* abi0 for apple target; introduces |
| 817 | * necessery sign extension for arg | 797 | * necessery sign extension for arg |
| 818 | * passing & returns | 798 | * passing & returns |
| @@ -29,7 +29,6 @@ bits arm64_retregs(Ref, int[2]); · 28 unmodified lines | |||
| 29 | bits arm64_argregs(Ref, int[2]); | 29 | bits arm64_argregs(Ref, int[2]); |
| 30 | void arm64_abi(Fn *); | 30 | void arm64_abi(Fn *); |
| 31 | void apple_extsb(Fn *); | 31 | void apple_extsb(Fn *); |
| 32 | void apple_abi(Fn *); | ||
| 33 | 32 | ||
| 34 | /* isel.c */ | 33 | /* isel.c */ |
| 35 | int arm64_logimm(uint64_t, int); | 34 | int arm64_logimm(uint64_t, int); |
| @@ -37,4 +36,3 @@ void arm64_isel(Fn *); · 1 unmodified line | |||
| 37 | 36 | ||
| 38 | /* emit.c */ | 37 | /* emit.c */ |
| 39 | void arm64_emitfn(Fn *, FILE *); | 38 | void arm64_emitfn(Fn *, FILE *); |
| 40 | void apple_emitfn(Fn *, FILE *); | ||
| @@ -7,7 +7,6 @@ struct E { · 6 unmodified lines | |||
| 7 | Fn *fn; | 7 | Fn *fn; |
| 8 | uint64_t frame; | 8 | uint64_t frame; |
| 9 | uint padding; | 9 | uint padding; |
| 10 | int apple; | ||
| 11 | }; | 10 | }; |
| 12 | 11 | ||
| 13 | #define CMP(X) \ | 12 | #define CMP(X) \ |
| @@ -145,7 +144,7 @@ slot(int s, E *e) · 131 unmodified lines | |||
| 145 | if (s == -1) | 144 | if (s == -1) |
| 146 | return 16 + e->frame; | 145 | return 16 + e->frame; |
| 147 | if (s < 0) { | 146 | if (s < 0) { |
| 148 | if (e->fn->vararg && !e->apple) | 147 | if (e->fn->vararg && !T.apple) |
| 149 | return 16 + e->frame + 192 - (s+2); | 148 | return 16 + e->frame + 192 - (s+2); |
| 150 | else | 149 | else |
| 151 | return 16 + e->frame - (s+2); | 150 | return 16 + e->frame - (s+2); |
| @@ -270,8 +269,8 @@ loadaddr(Con *c, char *rn, E *e) · 118 unmodified lines | |||
| 270 | fprintf(e->f, "\tadd\t%s, %s, #:tprel_lo12_nc:%s%s%s\n", | 269 | fprintf(e->f, "\tadd\t%s, %s, #:tprel_lo12_nc:%s%s%s\n", |
| 271 | rn, rn, p, l, off); | 270 | rn, rn, p, l, off); |
| 272 | } else { | 271 | } else { |
| 273 | fprintf(e->f, ldsym[e->apple][0], rn, p, l, off); | 272 | fprintf(e->f, ldsym[T.apple != 0][0], rn, p, l, off); |
| 274 | fprintf(e->f, ldsym[e->apple][1], rn, rn, p, l, off); | 273 | fprintf(e->f, ldsym[T.apple != 0][1], rn, rn, p, l, off); |
| 275 | } | 274 | } |
| 276 | } | 275 | } |
| 277 | 276 | ||
| @@ -472,8 +471,8 @@ framelayout(E *e) · 194 unmodified lines | |||
| 472 | 471 | ||
| 473 | */ | 472 | */ |
| 474 | 473 | ||
| 475 | static void | 474 | void |
| 476 | emitfn(E *e) | 475 | arm64_emitfn(Fn *fn, FILE *out) |
| 477 | { | 476 | { |
| 478 | static char *ctoa[] = { | 477 | static char *ctoa[] = { |
| 479 | #define X(c, s) [c] = s, | 478 | #define X(c, s) [c] = s, |
| @@ -485,11 +484,15 @@ emitfn(E *e) · 5 unmodified lines | |||
| 485 | uint64_t o; | 484 | uint64_t o; |
| 486 | Blk *b, *t; | 485 | Blk *b, *t; |
| 487 | Ins *i; | 486 | Ins *i; |
| 487 | E *e; | ||
| 488 | 488 | ||
| 489 | e = &(E){.f = out, .fn = fn}; | ||
| 490 | if (T.apple) | ||
| 491 | e->fn->lnk.align = 4; | ||
| 489 | emitfnlnk(e->fn->name, &e->fn->lnk, e->f); | 492 | emitfnlnk(e->fn->name, &e->fn->lnk, e->f); |
| 490 | framelayout(e); | 493 | framelayout(e); |
| 491 | 494 | ||
| 492 | if (e->fn->vararg && !e->apple) { | 495 | if (e->fn->vararg && !T.apple) { |
| 493 | for (n=7; n>=0; n--) | 496 | for (n=7; n>=0; n--) |
| 494 | fprintf(e->f, "\tstr\tq%d, [sp, -16]!\n", n); | 497 | fprintf(e->f, "\tstr\tq%d, [sp, -16]!\n", n); |
| 495 | for (n=7; n>=0; n-=2) | 498 | for (n=7; n>=0; n-=2) |
| @@ -551,7 +554,7 @@ emitfn(E *e) · 55 unmodified lines | |||
| 551 | if (e->fn->dynalloc) | 554 | if (e->fn->dynalloc) |
| 552 | fputs("\tmov sp, x29\n", e->f); | 555 | fputs("\tmov sp, x29\n", e->f); |
| 553 | o = e->frame + 16; | 556 | o = e->frame + 16; |
| 554 | if (e->fn->vararg && !e->apple) | 557 | if (e->fn->vararg && !T.apple) |
| 555 | o += 192; | 558 | o += 192; |
| 556 | if (o <= 504) | 559 | if (o <= 504) |
| 557 | fprintf(e->f, | 560 | fprintf(e->f, |
| @@ -610,17 +613,3 @@ emitfn(E *e) · 52 unmodified lines | |||
| 610 | } | 613 | } |
| 611 | id0 += e->fn->nblk; | 614 | id0 += e->fn->nblk; |
| 612 | } | 615 | } |
| 613 | |||
| 614 | void | ||
| 615 | arm64_emitfn(Fn *fn, FILE *out) | ||
| 616 | { | ||
| 617 | emitfn(&(E){.f = out, .fn = fn, .apple = 0}); | ||
| 618 | elf_emitfnfin(fn->name, out); | ||
| 619 | } | ||
| 620 | |||
| 621 | void | ||
| 622 | apple_emitfn(Fn *fn, FILE *out) | ||
| 623 | { | ||
| 624 | fn->lnk.align = 4; | ||
| 625 | emitfn(&(E){.f = out, .fn = fn, .apple = 1}); | ||
| 626 | } | ||
| @@ -38,12 +38,12 @@ arm64_memargs(int op) · 37 unmodified lines | |||
| 38 | .argregs = arm64_argregs, \ | 38 | .argregs = arm64_argregs, \ |
| 39 | .memargs = arm64_memargs, \ | 39 | .memargs = arm64_memargs, \ |
| 40 | .isel = arm64_isel, \ | 40 | .isel = arm64_isel, \ |
| 41 | .abi1 = arm64_abi, \ | ||
| 42 | .emitfn = arm64_emitfn, \ | ||
| 41 | 43 | ||
| 42 | Target T_arm64 = { | 44 | Target T_arm64 = { |
| 43 | .name = "arm64", | 45 | .name = "arm64", |
| 44 | .abi0 = elimsb, | 46 | .abi0 = elimsb, |
| 45 | .abi1 = arm64_abi, | ||
| 46 | .emitfn = arm64_emitfn, | ||
| 47 | .emitfin = elf_emitfin, | 47 | .emitfin = elf_emitfin, |
| 48 | .asloc = ".L", | 48 | .asloc = ".L", |
| 49 | ARM64_COMMON | 49 | ARM64_COMMON |
| @@ -51,9 +51,8 @@ Target T_arm64 = { · 1 unmodified line | |||
| 51 | 51 | ||
| 52 | Target T_arm64_apple = { | 52 | Target T_arm64_apple = { |
| 53 | .name = "arm64_apple", | 53 | .name = "arm64_apple", |
| 54 | .apple = 1, | ||
| 54 | .abi0 = apple_extsb, | 55 | .abi0 = apple_extsb, |
| 55 | .abi1 = apple_abi, | ||
| 56 | .emitfn = apple_emitfn, | ||
| 57 | .emitfin = macho_emitfin, | 56 | .emitfin = macho_emitfin, |
| 58 | .asloc = "L", | 57 | .asloc = "L", |
| 59 | .assym = "_", | 58 | .assym = "_", |