diff -Nru /n/sources/plan9/sys/src/cmd/5c/5.out.h /sys/src/cmd/5c/5.out.h --- /n/sources/plan9/sys/src/cmd/5c/5.out.h Sat Apr 7 20:07:16 2012 +++ /sys/src/cmd/5c/5.out.h Mon Dec 14 00:00:00 2015 @@ -93,8 +93,6 @@ AMULD, ADIVF, ADIVD, -// ASQRTF, -// ASQRTD, ASRL, ASRA, @@ -146,7 +144,6 @@ ASIGNAME, - /* moved here to preserve values of older identifiers */ ASQRTF, ASQRTD, @@ -156,6 +153,54 @@ ALDREXD, ASTREXD, + AERET, + AWFE, + AWFI, + + ACPS, + ACPSID, + ACPSIE, + + ADMB, + ADSB, + AISB, + + ACLZ, + + ACLREX, + ALDREXB, + ASTREXB, + ALDREXH, + ASTREXH, + + AABSF, + AABSD, + ANEGF, + ANEGD, + + AMLAF, + AMLAD, + AMLSF, + AMLSD, + ANMULF, + ANMULD, + ANMLAF, + ANMLAD, + ANMLSF, + ANMLSD, + + AMOVWFU, + AMOVWDU, + AMOVFWU, + AMOVDWU, + + AMOVMF, + AMOVMD, + APOPF, + APOPD, + APUSHF, + APUSHD, + ALAST, }; @@ -179,7 +224,7 @@ #define D_SCONST (D_NONE+9) #define D_PSR (D_NONE+10) #define D_REG (D_NONE+12) -#define D_FREG (D_NONE+13) +#define D_FREG (D_NONE+13) /* Fn = S(2*n) or Dn depending on op */ #define D_FILE (D_NONE+16) #define D_OCONST (D_NONE+17) #define D_FILE1 (D_NONE+18) @@ -188,6 +233,9 @@ #define D_FPCR (D_NONE+20) #define D_REGREG (D_NONE+21) #define D_ADDR (D_NONE+22) +#define D_VFPCR (D_NONE+23) +#define D_SFREG (D_NONE+24) /* single-precision register Sn */ +#define D_QREG (D_NONE+25) /* name */ #define D_EXTERN (D_NONE+3) diff -Nru /n/sources/plan9/sys/src/cmd/5c/cgen.c /sys/src/cmd/5c/cgen.c --- /n/sources/plan9/sys/src/cmd/5c/cgen.c Fri Sep 20 21:44:32 2013 +++ /sys/src/cmd/5c/cgen.c Mon Dec 14 00:00:00 2015 @@ -1,5 +1,7 @@ #include "gc.h" +static void genasop(int, Node*, Node*, Node *); + void cgen(Node *n, Node *nn) { @@ -54,7 +56,7 @@ cgen(r, &nod); regsalloc(&nod1, r); - gopcode(OAS, &nod, Z, &nod1); + gmove(&nod, &nod1); regfree(&nod); nod = *n; @@ -244,7 +246,7 @@ reglcgen(&nod2, l, Z); else nod2 = *l; - regalloc(&nod, r, nn); + regalloc(&nod, l, nn); gopcode(OAS, &nod2, Z, &nod); gopcode(o, r, Z, &nod); gopcode(OAS, &nod, Z, &nod2); @@ -254,6 +256,8 @@ regfree(&nod2); break; } + genasop(o, l, r, nn); + break; case OASLMUL: case OASLDIV: @@ -263,32 +267,7 @@ case OASMOD: if(l->op == OBIT) goto asbitop; - if(l->complex >= r->complex) { - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - regalloc(&nod1, r, Z); - cgen(r, &nod1); - } else { - regalloc(&nod1, r, Z); - cgen(r, &nod1); - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - } - - regalloc(&nod, n, nn); - gmove(&nod2, &nod); - gopcode(o, &nod1, Z, &nod); - gmove(&nod, &nod2); - if(nn != Z) - gopcode(OAS, &nod, Z, nn); - regfree(&nod); - regfree(&nod1); - if(l->addable < INDEXED) - regfree(&nod2); + genasop(o, l, r, nn); break; asbitop: @@ -319,6 +298,7 @@ break; case OFUNC: + l = uncomma(l); if(l->complex >= FNX) { if(l->op != OIND) diag(n, "bad function call"); @@ -564,6 +544,43 @@ return; } +static void +genasop(int o, Node *l, Node *r, Node *nn) +{ + Node nod, nod1, nod2; + int hardleft; + + hardleft = l->addable < INDEXED || l->complex >= FNX; + if(l->complex >= r->complex) { + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + regalloc(&nod1, r, Z); + cgen(r, &nod1); + } else { + regalloc(&nod1, r, Z); + cgen(r, &nod1); + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + } + if(nod1.type == nod2.type || !typefd[nod1.type->etype]) + regalloc(&nod, &nod2, nn); + else + regalloc(&nod, &nod1, Z); + gmove(&nod2, &nod); + gopcode(o, &nod1, Z, &nod); + gmove(&nod, &nod2); + if(nn != Z) + gmove(&nod2, nn); + regfree(&nod); + regfree(&nod1); + if(hardleft) + regfree(&nod2); +} + void reglcgen(Node *t, Node *n, Node *nn) { @@ -915,12 +932,12 @@ case OSTRUCT: /* - * rewrite so lhs has no fn call + * rewrite so lhs has no side effects */ - if(nn != Z && nn->complex >= FNX) { + if(nn != Z && side(nn)) { nod1 = *n; nod1.type = typ(TIND, n->type); - regret(&nod2, &nod1); + regalloc(&nod2, &nod1, Z); lcgen(nn, &nod2); regsalloc(&nod0, &nod1); gopcode(OAS, &nod2, Z, &nod0); @@ -999,6 +1016,7 @@ break; case OFUNC: + /* this transformation should probably be done earlier */ if(nn == Z) { sugen(n, nodrat, w); break; @@ -1010,6 +1028,7 @@ } else nn = nn->left; n = new(OFUNC, n->left, new(OLIST, nn, n->right)); + n->complex = FNX; n->type = types[TVOID]; n->left->type = types[TVOID]; cgen(n, Z); diff -Nru /n/sources/plan9/sys/src/cmd/5c/gc.h /sys/src/cmd/5c/gc.h --- /n/sources/plan9/sys/src/cmd/5c/gc.h Fri Sep 20 21:44:32 2013 +++ /sys/src/cmd/5c/gc.h Mon Dec 14 00:00:00 2015 @@ -51,8 +51,9 @@ Adr to; Prog* link; long lineno; - char as; + uchar as; char reg; + char reghi; /* for long multiply, double loads */ uchar scond; }; #define P ((Prog*)0) @@ -126,7 +127,7 @@ }; #define R ((Reg*)0) -#define NRGN 1000 /* was 600; raised for paranoia.c */ +#define NRGN 1000 struct Rgn { Reg* enter; @@ -172,6 +173,8 @@ #define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z]) #define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32)) + +#define isbigendian() align(0, types[TCHAR], Aarg1) #define CLOAD 4 #define CREF 5 @@ -344,6 +347,7 @@ int modifiescpsr(Prog *p); #pragma varargck type "A" int +#pragma varargck type "A" uint #pragma varargck type "B" Bits #pragma varargck type "D" Adr* #pragma varargck type "N" Adr* diff -Nru /n/sources/plan9/sys/src/cmd/5c/list.c /sys/src/cmd/5c/list.c --- /n/sources/plan9/sys/src/cmd/5c/list.c Thu Mar 28 20:57:13 2013 +++ /sys/src/cmd/5c/list.c Mon Dec 14 00:00:00 2015 @@ -84,7 +84,10 @@ if(p->reg == NREG) snprint(str, sizeof(str), " %A%s %D,%D", a, sc, &p->from, &p->to); else - if(p->from.type != D_FREG) + if(p->reghi != NREG) + snprint(str, sizeof(str), " %A%s %D,R%d,%D,R%d", a, sc, &p->from, p->reg, &p->to, p->reghi); + else + if(p->from.type != D_FREG && p->from.type != D_SFREG && p->from.type != D_FCONST) snprint(str, sizeof(str), " %A%s %D,R%d,%D", a, sc, &p->from, p->reg, &p->to); else snprint(str, sizeof(str), " %A%s %D,F%d,%D", a, sc, &p->from, p->reg, &p->to); @@ -158,6 +161,18 @@ case D_FREG: snprint(str, sizeof(str), "F%d", a->reg); + if(a->name != D_NONE || a->sym != S) + snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg); + break; + + case D_SFREG: + snprint(str, sizeof(str), "S%d", a->reg); + if(a->name != D_NONE || a->sym != S) + snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg); + break; + + case D_QREG: + snprint(str, sizeof(str), "Q%d", a->reg); if(a->name != D_NONE || a->sym != S) snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg); break; diff -Nru /n/sources/plan9/sys/src/cmd/5c/peep.c /sys/src/cmd/5c/peep.c --- /n/sources/plan9/sys/src/cmd/5c/peep.c Wed Mar 28 18:37:38 2012 +++ /sys/src/cmd/5c/peep.c Mon Dec 14 00:00:00 2015 @@ -306,6 +306,7 @@ case AAND: case AEOR: case AMUL: + case AMULU: case ADIV: case ADIVU: @@ -977,6 +978,7 @@ case AAND: case AEOR: case AMUL: + case AMULU: case ADIV: case ADIVU: case AADDF: @@ -1112,6 +1114,7 @@ case AAND: case AEOR: case AMUL: + case AMULU: case ADIV: case ADIVU: return D_REG; diff -Nru /n/sources/plan9/sys/src/cmd/6a/a.h /sys/src/cmd/6a/a.h --- /n/sources/plan9/sys/src/cmd/6a/a.h Mon May 23 18:57:41 2005 +++ /sys/src/cmd/6a/a.h Mon Dec 14 00:00:00 2015 @@ -156,6 +156,7 @@ void ieeedtod(Ieee*, double); int filbuf(void); Sym* getsym(void); +int isxyreg(int); void domacro(void); void macund(void); void macdef(void); diff -Nru /n/sources/plan9/sys/src/cmd/6a/a.y /sys/src/cmd/6a/a.y --- /n/sources/plan9/sys/src/cmd/6a/a.y Mon May 23 18:57:41 2005 +++ /sys/src/cmd/6a/a.y Mon Dec 14 00:00:00 2015 @@ -16,16 +16,16 @@ %left '+' '-' %left '*' '/' '%' %token LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 -%token LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT +%token LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG LTYPEXC LTYPEX LTYPEY LTYPERT %token LCONST LFP LPC LSB -%token LBREG LLREG LSREG LFREG LMREG LXREG +%token LBREG LLREG LSREG LFREG LMREG LXREG LYREG %token LFCONST %token LSCONST LSP %token LNAME LLAB LVAR %type con expr pointer offset %type mem imm reg nam rel rem rim rom omem nmem -%type nonnon nonrel nonrem rimnon rimrem remrim spec10 -%type spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 +%type nonnon nonrel nonrem rimnon rimrem remrim +%type spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12 %% prog: | prog line @@ -75,7 +75,9 @@ | LTYPEI spec7 { outcode($1, &$2); } | LTYPEXC spec8 { outcode($1, &$2); } | LTYPEX spec9 { outcode($1, &$2); } -| LTYPERT spec10 { outcode($1, &$2); } +| LTYPEG spec10 { outcode($1, &$2); } +| LTYPEY spec11 { outcode($1, &$2); } +| LTYPERT spec12 { outcode($1, &$2); } nonnon: { @@ -229,8 +231,17 @@ $$.to = $3; $$.from.offset = $5; } +| reg ',' reg ',' rem ',' con /* VCMPPS/VCMPPD */ + { + $$.from = $1; + if(!isxyreg($3.type)) + yyerror("second source operand must be X/Y register"); + $$.from.index = $3.type; + $$.to = $5; + $$.from.offset = $7; + } -spec9: /* shufl */ +spec9: /* SHUFL */ imm ',' rem ',' reg { $$.from = $3; @@ -239,8 +250,47 @@ yyerror("illegal constant"); $$.to.offset = $1.offset; } +| imm ',' rem ',' reg ',' reg + { + $$.from = $3; + $$.to = $7; + if($1.type != D_CONST) + yyerror("illegal constant"); + $$.to.offset = $1.offset; + if(!isxyreg($5.type)) + yyerror("second source operand must be X/Y register"); + $$.to.index = $5.type; + } -spec10: /* RET/RETF */ +spec10: /* GLOBL */ + mem ',' imm + { + $$.from = $1; + $$.to = $3; + } +| mem ',' con ',' imm + { + $$.from = $1; + $$.from.scale = $3; + $$.to = $5; + } + +spec11: + rimrem +| rim ',' reg ',' rem + { + $$.from = $1; + $$.to = $5; + if(isxyreg($3.type)) { + if(isxyreg($1.type)) + $$.from.index = $3.type; + else if(isxyreg($5.type)) + $$.to.index = $3.type; + } else + yyerror("second source operand must be X or Y register"); + } + +spec12: /* RET/RETF */ { $$.from = nullgen; $$.to = nullgen; @@ -268,6 +318,7 @@ } | reg | omem +| imm rim: rem @@ -333,6 +384,11 @@ $$ = nullgen; $$.type = $1; } +| LYREG + { + $$ = nullgen; + $$.type = $1; + } imm: '$' con @@ -427,6 +483,12 @@ { $$ = nullgen; $$.type = D_INDIR+D_SP; + } +| con '(' LSREG ')' + { + $$ = nullgen; + $$.type = D_INDIR+$3; + $$.offset = $1; } | '(' LLREG '*' con ')' { diff -Nru /n/sources/plan9/sys/src/cmd/6a/lex.c /sys/src/cmd/6a/lex.c --- /n/sources/plan9/sys/src/cmd/6a/lex.c Tue Dec 9 14:57:57 2008 +++ /sys/src/cmd/6a/lex.c Mon Dec 14 00:00:00 2015 @@ -121,7 +121,10 @@ setinclude(p); } else { if(systemtype(Plan9)) { - sprint(incfile,"/%s/include", thestring); + p = getenv("ccroot"); + if(p == nil) + p = ""; + snprint(incfile, sizeof(incfile), "%s/%s/include", p, thestring); setinclude(strdup(incfile)); } } @@ -206,6 +209,7 @@ "RARG", LLREG, REGARG, +/* "F0", LFREG, D_F0+0, "F1", LFREG, D_F0+1, "F2", LFREG, D_F0+2, @@ -214,6 +218,7 @@ "F5", LFREG, D_F0+5, "F6", LFREG, D_F0+6, "F7", LFREG, D_F0+7, +*/ "M0", LMREG, D_M0+0, "M1", LMREG, D_M0+1, @@ -241,6 +246,23 @@ "X14", LXREG, D_X0+14, "X15", LXREG, D_X0+15, + "Y0", LYREG, D_Y0+0, + "Y1", LYREG, D_Y0+1, + "Y2", LYREG, D_Y0+2, + "Y3", LYREG, D_Y0+3, + "Y4", LYREG, D_Y0+4, + "Y5", LYREG, D_Y0+5, + "Y6", LYREG, D_Y0+6, + "Y7", LYREG, D_Y0+7, + "Y8", LYREG, D_Y0+8, + "Y9", LYREG, D_Y0+9, + "Y10", LYREG, D_Y0+10, + "Y11", LYREG, D_Y0+11, + "Y12", LYREG, D_Y0+12, + "Y13", LYREG, D_Y0+13, + "Y14", LYREG, D_Y0+14, + "Y15", LYREG, D_Y0+15, + "CS", LSREG, D_CS, "SS", LSREG, D_SS, "DS", LSREG, D_DS, @@ -315,6 +337,8 @@ "BSRL", LTYPE3, ABSRL, "BSRQ", LTYPE3, ABSRQ, "BSRW", LTYPE3, ABSRW, + "BSWAPL", LTYPE1, ABSWAPL, + "BSWAPQ", LTYPE1, ABSWAPQ, "BTCL", LTYPE3, ABTCL, "BTCQ", LTYPE3, ABTCQ, "BTCW", LTYPE3, ABTCW, @@ -343,6 +367,7 @@ "CMPSQ", LTYPE0, ACMPSQ, "CMPSW", LTYPE0, ACMPSW, "CMPXCHG8B", LTYPE1, ACMPXCHG8B, + "CMPXCHG16B", LTYPE1, ACMPXCHG16B, "CMPXCHGB", LTYPE3, ACMPXCHGB, /* LTYPE3? */ "CMPXCHGL", LTYPE3, ACMPXCHGL, "CMPXCHGQ", LTYPE3, ACMPXCHGQ, @@ -475,6 +500,7 @@ "MOVLQZX", LTYPE3, AMOVLQZX, "MOVNTIL", LTYPE3, AMOVNTIL, "MOVNTIQ", LTYPE3, AMOVNTIQ, + "MOVQL", LTYPE3, AMOVQL, "MOVWLSX", LTYPE3, AMOVWLSX, "MOVWLZX", LTYPE3, AMOVWLZX, "MOVWQSX", LTYPE3, AMOVWQSX, @@ -506,8 +532,12 @@ "OUTSB", LTYPE0, AOUTSB, "OUTSL", LTYPE0, AOUTSL, "OUTSW", LTYPE0, AOUTSW, + "PAUSE", LTYPE0, APAUSE, "POPAL", LTYPE0, APOPAL, "POPAW", LTYPE0, APOPAW, + "POPCNTW", LTYPE3, APOPCNTW, + "POPCNTL", LTYPE3, APOPCNTL, + "POPCNTQ", LTYPE3, APOPCNTQ, "POPFL", LTYPE0, APOPFL, "POPFQ", LTYPE0, APOPFQ, "POPFW", LTYPE0, APOPFW, @@ -780,75 +810,77 @@ "FYL2X", LTYPE0, AFYL2X, "FYL2XP1", LTYPE0, AFYL2XP1, - "ADDPD", LTYPE3, AADDPD, - "ADDPS", LTYPE3, AADDPS, - "ADDSD", LTYPE3, AADDSD, - "ADDSS", LTYPE3, AADDSS, - "ANDNPD", LTYPE3, AANDNPD, - "ANDNPS", LTYPE3, AANDNPS, - "ANDPD", LTYPE3, AANDPD, - "ANDPS", LTYPE3, AANDPS, + "ADDPD", LTYPEY, AADDPD, + "ADDPS", LTYPEY, AADDPS, + "ADDSD", LTYPEY, AADDSD, + "ADDSS", LTYPEY, AADDSS, + "ANDNPD", LTYPEY, AANDNPD, + "ANDNPS", LTYPEY, AANDNPS, + "ANDPD", LTYPEY, AANDPD, + "ANDPS", LTYPEY, AANDPS, "CMPPD", LTYPEXC,ACMPPD, "CMPPS", LTYPEXC,ACMPPS, "CMPSD", LTYPEXC,ACMPSD, "CMPSS", LTYPEXC,ACMPSS, - "COMISD", LTYPE3, ACOMISD, - "COMISS", LTYPE3, ACOMISS, - "CVTPL2PD", LTYPE3, ACVTPL2PD, - "CVTPL2PS", LTYPE3, ACVTPL2PS, - "CVTPD2PL", LTYPE3, ACVTPD2PL, - "CVTPD2PS", LTYPE3, ACVTPD2PS, - "CVTPS2PL", LTYPE3, ACVTPS2PL, - "PF2IW", LTYPE3, APF2IW, - "PF2IL", LTYPE3, APF2IL, - "PF2ID", LTYPE3, APF2IL, /* syn */ - "PI2FL", LTYPE3, API2FL, - "PI2FD", LTYPE3, API2FL, /* syn */ - "PI2FW", LTYPE3, API2FW, - "CVTPS2PD", LTYPE3, ACVTPS2PD, - "CVTSD2SL", LTYPE3, ACVTSD2SL, - "CVTSD2SQ", LTYPE3, ACVTSD2SQ, - "CVTSD2SS", LTYPE3, ACVTSD2SS, - "CVTSL2SD", LTYPE3, ACVTSL2SD, - "CVTSQ2SD", LTYPE3, ACVTSQ2SD, - "CVTSL2SS", LTYPE3, ACVTSL2SS, - "CVTSQ2SS", LTYPE3, ACVTSQ2SS, - "CVTSS2SD", LTYPE3, ACVTSS2SD, - "CVTSS2SL", LTYPE3, ACVTSS2SL, - "CVTSS2SQ", LTYPE3, ACVTSS2SQ, - "CVTTPD2PL", LTYPE3, ACVTTPD2PL, - "CVTTPS2PL", LTYPE3, ACVTTPS2PL, - "CVTTSD2SL", LTYPE3, ACVTTSD2SL, - "CVTTSD2SQ", LTYPE3, ACVTTSD2SQ, - "CVTTSS2SL", LTYPE3, ACVTTSS2SL, - "CVTTSS2SQ", LTYPE3, ACVTTSS2SQ, - "DIVPD", LTYPE3, ADIVPD, - "DIVPS", LTYPE3, ADIVPS, - "DIVSD", LTYPE3, ADIVSD, - "DIVSS", LTYPE3, ADIVSS, + "COMISD", LTYPEY, ACOMISD, + "COMISS", LTYPEY, ACOMISS, + "CVTPL2PD", LTYPEY, ACVTPL2PD, + "CVTPL2PS", LTYPEY, ACVTPL2PS, + "CVTPD2PL", LTYPEY, ACVTPD2PL, + "CVTPD2PS", LTYPEY, ACVTPD2PS, + "CVTPS2PL", LTYPEY, ACVTPS2PL, + "PF2IW", LTYPEY, APF2IW, + "PF2IL", LTYPEY, APF2IL, + "PF2ID", LTYPEY, APF2IL, /* syn */ + "PI2FL", LTYPEY, API2FL, + "PI2FD", LTYPEY, API2FL, /* syn */ + "PI2FW", LTYPEY, API2FW, + "CVTPS2PD", LTYPEY, ACVTPS2PD, + "CVTSD2SL", LTYPEY, ACVTSD2SL, + "CVTSD2SQ", LTYPEY, ACVTSD2SQ, + "CVTSD2SS", LTYPEY, ACVTSD2SS, + "CVTSL2SD", LTYPEY, ACVTSL2SD, + "CVTSQ2SD", LTYPEY, ACVTSQ2SD, + "CVTSL2SS", LTYPEY, ACVTSL2SS, + "CVTSQ2SS", LTYPEY, ACVTSQ2SS, + "CVTSS2SD", LTYPEY, ACVTSS2SD, + "CVTSS2SL", LTYPEY, ACVTSS2SL, + "CVTSS2SQ", LTYPEY, ACVTSS2SQ, + "CVTTPD2PL", LTYPEY, ACVTTPD2PL, + "CVTTPS2PL", LTYPEY, ACVTTPS2PL, + "CVTTSD2SL", LTYPEY, ACVTTSD2SL, + "CVTTSD2SQ", LTYPEY, ACVTTSD2SQ, + "CVTTSS2SL", LTYPEY, ACVTTSS2SL, + "CVTTSS2SQ", LTYPEY, ACVTTSS2SQ, + "DIVPD", LTYPEY, ADIVPD, + "DIVPS", LTYPEY, ADIVPS, + "DIVSD", LTYPEY, ADIVSD, + "DIVSS", LTYPEY, ADIVSS, "FXRSTOR", LTYPE2, AFXRSTOR, "FXRSTOR64", LTYPE2, AFXRSTOR64, "FXSAVE", LTYPE1, AFXSAVE, "FXSAVE64", LTYPE1, AFXSAVE64, "LDMXCSR", LTYPE2, ALDMXCSR, - "MASKMOVOU", LTYPE3, AMASKMOVOU, - "MASKMOVDQU", LTYPE3, AMASKMOVOU, /* syn */ + "MASKMOVDQU", LTYPE3, AMASKMOVDQU, "MASKMOVQ", LTYPE3, AMASKMOVQ, - "MAXPD", LTYPE3, AMAXPD, - "MAXPS", LTYPE3, AMAXPS, - "MAXSD", LTYPE3, AMAXSD, - "MAXSS", LTYPE3, AMAXSS, - "MINPD", LTYPE3, AMINPD, - "MINPS", LTYPE3, AMINPS, - "MINSD", LTYPE3, AMINSD, - "MINSS", LTYPE3, AMINSS, + "MAXPD", LTYPEY, AMAXPD, + "MAXPS", LTYPEY, AMAXPS, + "MAXSD", LTYPEY, AMAXSD, + "MAXSS", LTYPEY, AMAXSS, + "MINPD", LTYPEY, AMINPD, + "MINPS", LTYPEY, AMINPS, + "MINSD", LTYPEY, AMINSD, + "MINSS", LTYPEY, AMINSS, "MOVAPD", LTYPE3, AMOVAPD, "MOVAPS", LTYPE3, AMOVAPS, "MOVD", LTYPE3, AMOVQ, /* syn */ "MOVDQ2Q", LTYPE3, AMOVQ, /* syn */ "MOVO", LTYPE3, AMOVO, - "MOVOA", LTYPE3, AMOVO, /* syn */ - "MOVOU", LTYPE3, AMOVOU, + "MOVOA", LTYPE3, AMOVDQA, /* syn */ + "MOVDQA", LTYPE3, AMOVDQA, + "MOVDQU", LTYPE3, AMOVDQU, + "MOVQQA", LTYPE3, AMOVQQA, + "MOVQQU", LTYPE3, AMOVQQU, "MOVHLPS", LTYPE3, AMOVHLPS, "MOVHPD", LTYPE3, AMOVHPD, "MOVHPS", LTYPE3, AMOVHPS, @@ -857,8 +889,7 @@ "MOVLPS", LTYPE3, AMOVLPS, "MOVMSKPD", LTYPE3, AMOVMSKPD, "MOVMSKPS", LTYPE3, AMOVMSKPS, - "MOVNTO", LTYPE3, AMOVNTO, - "MOVNTDQ", LTYPE3, AMOVNTO, /* syn */ + "MOVNTDQ", LTYPE3, AMOVNTDQ, "MOVNTPD", LTYPE3, AMOVNTPD, "MOVNTPS", LTYPE3, AMOVNTPS, "MOVNTQ", LTYPE3, AMOVNTQ, @@ -867,115 +898,472 @@ "MOVSS", LTYPE3, AMOVSS, "MOVUPD", LTYPE3, AMOVUPD, "MOVUPS", LTYPE3, AMOVUPS, - "MULPD", LTYPE3, AMULPD, - "MULPS", LTYPE3, AMULPS, - "MULSD", LTYPE3, AMULSD, - "MULSS", LTYPE3, AMULSS, - "ORPD", LTYPE3, AORPD, - "ORPS", LTYPE3, AORPS, - "PACKSSLW", LTYPE3, APACKSSLW, - "PACKSSWB", LTYPE3, APACKSSWB, - "PACKUSWB", LTYPE3, APACKUSWB, - "PADDB", LTYPE3, APADDB, - "PADDL", LTYPE3, APADDL, - "PADDQ", LTYPE3, APADDQ, - "PADDSB", LTYPE3, APADDSB, - "PADDSW", LTYPE3, APADDSW, - "PADDUSB", LTYPE3, APADDUSB, - "PADDUSW", LTYPE3, APADDUSW, - "PADDW", LTYPE3, APADDW, - "PAND", LTYPE3, APAND, - "PANDB", LTYPE3, APANDB, - "PANDL", LTYPE3, APANDL, - "PANDSB", LTYPE3, APANDSB, - "PANDSW", LTYPE3, APANDSW, - "PANDUSB", LTYPE3, APANDUSB, - "PANDUSW", LTYPE3, APANDUSW, - "PANDW", LTYPE3, APANDW, - "PANDN", LTYPE3, APANDN, - "PAVGB", LTYPE3, APAVGB, - "PAVGW", LTYPE3, APAVGW, - "PCMPEQB", LTYPE3, APCMPEQB, - "PCMPEQL", LTYPE3, APCMPEQL, - "PCMPEQW", LTYPE3, APCMPEQW, - "PCMPGTB", LTYPE3, APCMPGTB, - "PCMPGTL", LTYPE3, APCMPGTL, - "PCMPGTW", LTYPE3, APCMPGTW, + "MULPD", LTYPEY, AMULPD, + "MULPS", LTYPEY, AMULPS, + "MULSD", LTYPEY, AMULSD, + "MULSS", LTYPEY, AMULSS, + "ORPD", LTYPEY, AORPD, + "ORPS", LTYPEY, AORPS, + "PACKSSLW", LTYPEY, APACKSSLW, + "PACKSSWB", LTYPEY, APACKSSWB, + "PACKUSWB", LTYPEY, APACKUSWB, + "PADDB", LTYPEY, APADDB, + "PADDL", LTYPEY, APADDL, + "PADDQ", LTYPEY, APADDQ, + "PADDSB", LTYPEY, APADDSB, + "PADDSW", LTYPEY, APADDSW, + "PADDUSB", LTYPEY, APADDUSB, + "PADDUSW", LTYPEY, APADDUSW, + "PADDW", LTYPEY, APADDW, + "PAND", LTYPEY, APAND, + "PANDB", LTYPEY, APANDB, + "PANDL", LTYPEY, APANDL, + "PANDSB", LTYPEY, APANDSB, + "PANDSW", LTYPEY, APANDSW, + "PANDUSB", LTYPEY, APANDUSB, + "PANDUSW", LTYPEY, APANDUSW, + "PANDW", LTYPEY, APANDW, + "PANDN", LTYPEY, APANDN, + "PAVGB", LTYPEY, APAVGB, + "PAVGW", LTYPEY, APAVGW, + "PCMPEQB", LTYPEY, APCMPEQB, + "PCMPEQL", LTYPEY, APCMPEQL, + "PCMPEQW", LTYPEY, APCMPEQW, + "PCMPGTB", LTYPEY, APCMPGTB, + "PCMPGTL", LTYPEY, APCMPGTL, + "PCMPGTW", LTYPEY, APCMPGTW, "PEXTRW", LTYPEX, APEXTRW, "PINSRW", LTYPEX, APINSRW, - "PMADDWL", LTYPE3, APMADDWL, - "PMAXSW", LTYPE3, APMAXSW, - "PMAXUB", LTYPE3, APMAXUB, - "PMINSW", LTYPE3, APMINSW, - "PMINUB", LTYPE3, APMINUB, + "PMADDWL", LTYPEY, APMADDWL, + "PMAXSW", LTYPEY, APMAXSW, + "PMAXUB", LTYPEY, APMAXUB, + "PMINSW", LTYPEY, APMINSW, + "PMINUB", LTYPEY, APMINUB, "PMOVMSKB", LTYPE3, APMOVMSKB, - "PMULHRW", LTYPE3, APMULHRW, - "PMULHUW", LTYPE3, APMULHUW, - "PMULHW", LTYPE3, APMULHW, - "PMULLW", LTYPE3, APMULLW, - "PMULULQ", LTYPE3, APMULULQ, - "POR", LTYPE3, APOR, - "PSADBW", LTYPE3, APSADBW, + "PMULHRW", LTYPEY, APMULHRW, + "PMULHUW", LTYPEY, APMULHUW, + "PMULHW", LTYPEY, APMULHW, + "PMULLW", LTYPEY, APMULLW, + "PMULULQ", LTYPEY, APMULULQ, + "POR", LTYPEY, APOR, + "PSADBW", LTYPEY, APSADBW, "PSHUFHW", LTYPEX, APSHUFHW, "PSHUFL", LTYPEX, APSHUFL, "PSHUFLW", LTYPEX, APSHUFLW, "PSHUFW", LTYPEX, APSHUFW, - "PSLLO", LTYPE3, APSLLO, - "PSLLDQ", LTYPE3, APSLLO, /* syn */ - "PSLLL", LTYPE3, APSLLL, - "PSLLQ", LTYPE3, APSLLQ, - "PSLLW", LTYPE3, APSLLW, - "PSRAL", LTYPE3, APSRAL, - "PSRAW", LTYPE3, APSRAW, - "PSRLO", LTYPE3, APSRLO, - "PSRLDQ", LTYPE3, APSRLO, /* syn */ - "PSRLL", LTYPE3, APSRLL, - "PSRLQ", LTYPE3, APSRLQ, - "PSRLW", LTYPE3, APSRLW, - "PSUBB", LTYPE3, APSUBB, - "PSUBL", LTYPE3, APSUBL, - "PSUBQ", LTYPE3, APSUBQ, - "PSUBSB", LTYPE3, APSUBSB, - "PSUBSW", LTYPE3, APSUBSW, - "PSUBUSB", LTYPE3, APSUBUSB, - "PSUBUSW", LTYPE3, APSUBUSW, - "PSUBW", LTYPE3, APSUBW, - "PUNPCKHBW", LTYPE3, APUNPCKHBW, - "PUNPCKHLQ", LTYPE3, APUNPCKHLQ, - "PUNPCKHQDQ", LTYPE3, APUNPCKHQDQ, - "PUNPCKHWL", LTYPE3, APUNPCKHWL, - "PUNPCKLBW", LTYPE3, APUNPCKLBW, - "PUNPCKLLQ", LTYPE3, APUNPCKLLQ, - "PUNPCKLQDQ", LTYPE3, APUNPCKLQDQ, - "PUNPCKLWL", LTYPE3, APUNPCKLWL, - "PXOR", LTYPE3, APXOR, - "RCPPS", LTYPE3, ARCPPS, - "RCPSS", LTYPE3, ARCPSS, - "RSQRTPS", LTYPE3, ARSQRTPS, - "RSQRTSS", LTYPE3, ARSQRTSS, + "PSLLDQ", LTYPEY, APSLLDQ, + "PSLLL", LTYPEY, APSLLL, + "PSLLQ", LTYPEY, APSLLQ, + "PSLLW", LTYPEY, APSLLW, + "PSRAL", LTYPEY, APSRAL, + "PSRAW", LTYPEY, APSRAW, + "PSRLDQ", LTYPEY, APSRLDQ, + "PSRLL", LTYPEY, APSRLL, + "PSRLQ", LTYPEY, APSRLQ, + "PSRLW", LTYPEY, APSRLW, + "PSUBB", LTYPEY, APSUBB, + "PSUBL", LTYPEY, APSUBL, + "PSUBQ", LTYPEY, APSUBQ, + "PSUBSB", LTYPEY, APSUBSB, + "PSUBSW", LTYPEY, APSUBSW, + "PSUBUSB", LTYPEY, APSUBUSB, + "PSUBUSW", LTYPEY, APSUBUSW, + "PSUBW", LTYPEY, APSUBW, + "PUNPCKHBW", LTYPEY, APUNPCKHBW, + "PUNPCKHLQ", LTYPEY, APUNPCKHLQ, + "PUNPCKHQDQ", LTYPEY, APUNPCKHQDQ, + "PUNPCKHWL", LTYPEY, APUNPCKHWL, + "PUNPCKLBW", LTYPEY, APUNPCKLBW, + "PUNPCKLLQ", LTYPEY, APUNPCKLLQ, + "PUNPCKLQDQ", LTYPEY, APUNPCKLQDQ, + "PUNPCKLWL", LTYPEY, APUNPCKLWL, + "PXOR", LTYPEY, APXOR, + "RCPPS", LTYPEY, ARCPPS, + "RCPSS", LTYPEY, ARCPSS, + "RSQRTPS", LTYPEY, ARSQRTPS, + "RSQRTSS", LTYPEY, ARSQRTSS, "SHUFPD", LTYPEX, ASHUFPD, "SHUFPS", LTYPEX, ASHUFPS, - "SQRTPD", LTYPE3, ASQRTPD, - "SQRTPS", LTYPE3, ASQRTPS, - "SQRTSD", LTYPE3, ASQRTSD, - "SQRTSS", LTYPE3, ASQRTSS, + "SQRTPD", LTYPEY, ASQRTPD, + "SQRTPS", LTYPEY, ASQRTPS, + "SQRTSD", LTYPEY, ASQRTSD, + "SQRTSS", LTYPEY, ASQRTSS, "STMXCSR", LTYPE1, ASTMXCSR, - "SUBPD", LTYPE3, ASUBPD, - "SUBPS", LTYPE3, ASUBPS, - "SUBSD", LTYPE3, ASUBSD, - "SUBSS", LTYPE3, ASUBSS, - "UCOMISD", LTYPE3, AUCOMISD, - "UCOMISS", LTYPE3, AUCOMISS, - "UNPCKHPD", LTYPE3, AUNPCKHPD, - "UNPCKHPS", LTYPE3, AUNPCKHPS, - "UNPCKLPD", LTYPE3, AUNPCKLPD, - "UNPCKLPS", LTYPE3, AUNPCKLPS, - "XORPD", LTYPE3, AXORPD, - "XORPS", LTYPE3, AXORPS, - + "SUBPD", LTYPEY, ASUBPD, + "SUBPS", LTYPEY, ASUBPS, + "SUBSD", LTYPEY, ASUBSD, + "SUBSS", LTYPEY, ASUBSS, + "UCOMISD", LTYPEY, AUCOMISD, + "UCOMISS", LTYPEY, AUCOMISS, + "UNPCKHPD", LTYPEY, AUNPCKHPD, + "UNPCKHPS", LTYPEY, AUNPCKHPS, + "UNPCKLPD", LTYPEY, AUNPCKLPD, + "UNPCKLPS", LTYPEY, AUNPCKLPS, + "XORPD", LTYPEY, AXORPD, + "XORPS", LTYPEY, AXORPS, + "XSAVE", LTYPE1, AXSAVE, + "XSAVEOPT", LTYPE1, AXSAVEOPT, + "XRSTOR", LTYPE2, AXRSTOR, + + /* sse/vex */ + "AESDEC", LTYPEY, AAESDEC, + "AESDECLAST", LTYPEY, AAESDECLAST, + "AESENC", LTYPEY, AAESENC, + "AESENCLAST", LTYPEY, AAESENCLAST, + "AESIMC", LTYPEY, AAESIMC, + "AESKEYGENASSIST", LTYPEY, AAESKEYGENASSIST, + "BLENDPD", LTYPEY, ABLENDPD, + "BLENDPS", LTYPEY, ABLENDPS, + "BLENDVPD", LTYPEY, ABLENDVPD, + "BLENDVPS", LTYPEY, ABLENDVPS, + "CRC32B", LTYPE3, ACRC32B, + "CRC32L", LTYPE3, ACRC32L, + "CRC32Q", LTYPE3, ACRC32Q, + "CRC32W", LTYPE3, ACRC32W, + "DPPD", LTYPEY, ADPPD, + "DPPS", LTYPEY, ADPPS, + "EXTRACTPS", LTYPEY, AEXTRACTPS, + "INSERTPS", LTYPEY, AINSERTPS, + "MOVNTDQA", LTYPEY, AMOVNTDQA, + "MPSADBW", LTYPEY, AMPSADBW, + "PABSB", LTYPEY, APABSB, + "PABSL", LTYPEY, APABSL, + "PABSD", LTYPEY, APABSL, /* syn */ + "PABSW", LTYPEY, APABSW, + "PACKUSDW", LTYPEY, APACKUSDW, + "PALIGNR", LTYPEX, APALIGNR, + "PBLENDVB", LTYPEY, APBLENDVB, + "PBLENDW", LTYPEY, APBLENDW, + "PCLMULHQHQDQ", LTYPEY, APCLMULHQHQDQ, + "PCLMULHQLQDQ", LTYPEY, APCLMULHQLQDQ, + "PCLMULLQHQDQ", LTYPEY, APCLMULLQHQDQ, + "PCLMULLQLQDQ", LTYPEY, APCLMULLQLQDQ, + "PCLMULQDQ", LTYPEY, APCLMULQDQ, + "PCMPEQQ", LTYPEY, APCMPEQQ, + "PCMPESTRI", LTYPEY, APCMPESTRI, + "PCMPESTRM", LTYPEY, APCMPESTRM, + "PCMPGTQ", LTYPEY, APCMPGTQ, + "PCMPISTRI", LTYPEY, APCMPISTRI, + "PCMPISTRM", LTYPEY, APCMPISTRM, + "PEXTRB", LTYPEY, APEXTRB, + "PEXTRL", LTYPEY, APEXTRL, + "PHADDL", LTYPEY, APHADDL, + "PHADDSW", LTYPEY, APHADDSW, + "PHADDW", LTYPEY, APHADDW, + "PHMINPOSUW", LTYPEY, APHMINPOSUW, + "PHSUBL", LTYPEY, APHSUBL, + "PHSUBSW", LTYPEY, APHSUBSW, + "PHSUBW", LTYPEY, APHSUBW, + "PINSRB", LTYPEY, APINSRB, + "PINSRL", LTYPEY, APINSRL, + "PMADDUBSW", LTYPEY, APMADDUBSW, + "PMAXSB", LTYPEY, APMAXSB, + "PMAXSL", LTYPEY, APMAXSL, + "PMAXUL", LTYPEY, APMAXUL, + "PMAXUW", LTYPEY, APMAXUW, + "PMINSB", LTYPEY, APMINSB, + "PMINSL", LTYPEY, APMINSL, + "PMINUL", LTYPEY, APMINUL, + "PMINUW", LTYPEY, APMINUW, + "PMOVSXBL", LTYPEY, APMOVSXBL, + "PMOVSXBQ", LTYPEY, APMOVSXBQ, + "PMOVSXBW", LTYPEY, APMOVSXBW, + "PMOVSXLQ", LTYPEY, APMOVSXLQ, + "PMOVSXWL", LTYPEY, APMOVSXWL, + "PMOVSXWQ", LTYPEY, APMOVSXWQ, + "PMOVZXBL", LTYPEY, APMOVZXBL, + "PMOVZXBQ", LTYPEY, APMOVZXBQ, + "PMOVZXBW", LTYPEY, APMOVZXBW, + "PMOVZXLQ", LTYPEY, APMOVZXLQ, + "PMOVZXWL", LTYPEY, APMOVZXWL, + "PMOVZXWQ", LTYPEY, APMOVZXWQ, + "PMULHRSW", LTYPEY, APMULHRSW, + "PMULLL", LTYPEY, APMULLL, + "PMULLQ", LTYPEY, APMULLQ, + "PSHUFB", LTYPEY, APSHUFB, + "PSIGNB", LTYPEY, APSIGNB, + "PSIGNL", LTYPEY, APSIGNL, + "PSIGNW", LTYPEY, APSIGNW, + "PTEST", LTYPEY, APTEST, + "ROUNDPD", LTYPEY, AROUNDPD, + "ROUNDPS", LTYPEY, AROUNDPS, + "ROUNDSD", LTYPEY, AROUNDSD, + "ROUNDSS", LTYPEY, AROUNDSS, + + /* vex only */ + "VBROADCASTF128", LTYPEY, AVBROADCASTF128, + "VBROADCASTSL", LTYPEY, AVBROADCASTSL, + "VBROADCASTSS", LTYPEY, AVBROADCASTSS, + "VMASKMOVPD", LTYPEY, AVMASKMOVPD, + "VMASKMOVPS", LTYPEY, AVMASKMOVPS, + "VPERMILPD", LTYPEY, AVPERMILPD, + "VPERMILPS", LTYPEY, AVPERMILPS, + "VTESTPD", LTYPEY, AVTESTPD, + "VTESTPS", LTYPEY, AVTESTPS, + + /* V* synonyms */ + "VADDPD", LTYPEY, AADDPD, + "VADDPS", LTYPEY, AADDPS, + "VADDSD", LTYPEY, AADDSD, + "VADDSS", LTYPEY, AADDSS, + "VANDNPD", LTYPEY, AANDNPD, + "VANDNPS", LTYPEY, AANDNPS, + "VANDPD", LTYPEY, AANDPD, + "VANDPS", LTYPEY, AANDPS, + "VCMPPD", LTYPEXC,ACMPPD, + "VCMPPS", LTYPEXC,ACMPPS, + "VCMPSD", LTYPEXC,ACMPSD, + "VCMPSS", LTYPEXC,ACMPSS, + "VCOMISD", LTYPEY, ACOMISD, + "VCOMISS", LTYPEY, ACOMISS, + "VCVTPL2PD", LTYPEY, ACVTPL2PD, + "VCVTPL2PS", LTYPEY, ACVTPL2PS, + "VCVTPD2PL", LTYPEY, ACVTPD2PL, + "VCVTPD2PS", LTYPEY, ACVTPD2PS, + "VCVTPS2PL", LTYPEY, ACVTPS2PL, + "VCVTPS2PD", LTYPEY, ACVTPS2PD, + "VCVTSD2SL", LTYPEY, ACVTSD2SL, + "VCVTSD2SQ", LTYPEY, ACVTSD2SQ, + "VCVTSD2SS", LTYPEY, ACVTSD2SS, + "VCVTSL2SD", LTYPEY, ACVTSL2SD, + "VCVTSQ2SD", LTYPEY, ACVTSQ2SD, + "VCVTSL2SS", LTYPEY, ACVTSL2SS, + "VCVTSQ2SS", LTYPEY, ACVTSQ2SS, + "VCVTSS2SD", LTYPEY, ACVTSS2SD, + "VCVTSS2SL", LTYPEY, ACVTSS2SL, + "VCVTSS2SQ", LTYPEY, ACVTSS2SQ, + "VCVTTPD2PL", LTYPEY, ACVTTPD2PL, + "VCVTTPS2PL", LTYPEY, ACVTTPS2PL, + "VCVTTSD2SL", LTYPEY, ACVTTSD2SL, + "VCVTTSS2SL", LTYPEY, ACVTTSS2SL, + "VDIVPD", LTYPEY, ADIVPD, + "VDIVPS", LTYPEY, ADIVPS, + "VDIVSD", LTYPEY, ADIVSD, + "VDIVSS", LTYPEY, ADIVSS, + "VLDMXCSR", LTYPE2, ALDMXCSR, + "VMASKMOVDQU", LTYPE3, AMASKMOVDQU, + "VMASKMOVQ", LTYPE3, AMASKMOVQ, + "VMAXPD", LTYPEY, AMAXPD, + "VMAXPS", LTYPEY, AMAXPS, + "VMAXSD", LTYPEY, AMAXSD, + "VMAXSS", LTYPEY, AMAXSS, + "VMINPD", LTYPEY, AMINPD, + "VMINPS", LTYPEY, AMINPS, + "VMINSD", LTYPEY, AMINSD, + "VMINSS", LTYPEY, AMINSS, + "VMOVAPD", LTYPE3, AMOVAPD, + "VMOVAPS", LTYPE3, AMOVAPS, + "VMOVD", LTYPE3, AMOVL, /* syn */ + "VMOVDQA", LTYPE3, AMOVDQA, + "VMOVDQU", LTYPE3, AMOVDQU, + "VMOVQ", LTYPE3, AMOVQ, + "VMOVQQA", LTYPE3, AMOVQQA, + "VMOVQQU", LTYPE3, AMOVQQU, + "VMOVHLPS", LTYPE3, AMOVHLPS, + "VMOVHPD", LTYPE3, AMOVHPD, + "VMOVHPS", LTYPE3, AMOVHPS, + "VMOVLHPS", LTYPE3, AMOVLHPS, + "VMOVLPD", LTYPE3, AMOVLPD, + "VMOVLPS", LTYPE3, AMOVLPS, + "VMOVMSKPD", LTYPE3, AMOVMSKPD, + "VMOVMSKPS", LTYPE3, AMOVMSKPS, + "VMOVNTDQ", LTYPE3, AMOVNTDQ, + "VMOVNTPD", LTYPE3, AMOVNTPD, + "VMOVNTPS", LTYPE3, AMOVNTPS, + "VMOVNTQ", LTYPE3, AMOVNTQ, + "VMOVSD", LTYPE3, AMOVSD, + "VMOVSS", LTYPE3, AMOVSS, + "VMOVUPD", LTYPE3, AMOVUPD, + "VMOVUPS", LTYPE3, AMOVUPS, + "VMULPD", LTYPEY, AMULPD, + "VMULPS", LTYPEY, AMULPS, + "VMULSD", LTYPEY, AMULSD, + "VMULSS", LTYPEY, AMULSS, + "VORPD", LTYPEY, AORPD, + "VORPS", LTYPEY, AORPS, + "VPACKSSLW", LTYPEY, APACKSSLW, + "VPACKSSWB", LTYPEY, APACKSSWB, + "VPACKUSWB", LTYPEY, APACKUSWB, + "VPADDB", LTYPEY, APADDB, + "VPADDL", LTYPEY, APADDL, + "VPADDQ", LTYPEY, APADDQ, + "VPADDSB", LTYPEY, APADDSB, + "VPADDSW", LTYPEY, APADDSW, + "VPADDUSB", LTYPEY, APADDUSB, + "VPADDUSW", LTYPEY, APADDUSW, + "VPADDW", LTYPEY, APADDW, + "VPAND", LTYPEY, APAND, + "VPANDB", LTYPEY, APANDB, + "VPANDL", LTYPEY, APANDL, + "VPANDSB", LTYPEY, APANDSB, + "VPANDSW", LTYPEY, APANDSW, + "VPANDUSB", LTYPEY, APANDUSB, + "VPANDUSW", LTYPEY, APANDUSW, + "VPANDW", LTYPEY, APANDW, + "VPANDN", LTYPEY, APANDN, + "VPAVGB", LTYPEY, APAVGB, + "VPAVGW", LTYPEY, APAVGW, + "VPCMPEQB", LTYPEY, APCMPEQB, + "VPCMPEQL", LTYPEY, APCMPEQL, + "VPCMPEQW", LTYPEY, APCMPEQW, + "VPCMPGTB", LTYPEY, APCMPGTB, + "VPCMPGTL", LTYPEY, APCMPGTL, + "VPCMPGTW", LTYPEY, APCMPGTW, + "VPEXTRW", LTYPEX, APEXTRW, + "VPINSRW", LTYPEX, APINSRW, + "VPMADDWL", LTYPEY, APMADDWL, + "VPMAXSW", LTYPEY, APMAXSW, + "VPMAXUB", LTYPEY, APMAXUB, + "VPMINSW", LTYPEY, APMINSW, + "VPMINUB", LTYPEY, APMINUB, + "VPMOVMSKB", LTYPE3, APMOVMSKB, + "VPMULHUW", LTYPEY, APMULHUW, + "VPMULHW", LTYPEY, APMULHW, + "VPMULLW", LTYPEY, APMULLW, + "VPMULULQ", LTYPEY, APMULULQ, + "VPOR", LTYPEY, APOR, + "VPSADBW", LTYPEY, APSADBW, + "VPSHUFHW", LTYPEX, APSHUFHW, + "VPSHUFL", LTYPEX, APSHUFL, + "VPSHUFLW", LTYPEX, APSHUFLW, + "VPSLLDQ", LTYPEY, APSLLDQ, + "VPSLLL", LTYPEY, APSLLL, + "VPSLLQ", LTYPEY, APSLLQ, + "VPSLLW", LTYPEY, APSLLW, + "VPSRAL", LTYPEY, APSRAL, + "VPSRAW", LTYPEY, APSRAW, + "VPSRLDQ", LTYPEY, APSRLDQ, + "VPSRLL", LTYPEY, APSRLL, + "VPSRLQ", LTYPEY, APSRLQ, + "VPSRLW", LTYPEY, APSRLW, + "VPSUBB", LTYPEY, APSUBB, + "VPSUBL", LTYPEY, APSUBL, + "VPSUBQ", LTYPEY, APSUBQ, + "VPSUBSB", LTYPEY, APSUBSB, + "VPSUBSW", LTYPEY, APSUBSW, + "VPSUBUSB", LTYPEY, APSUBUSB, + "VPSUBUSW", LTYPEY, APSUBUSW, + "VPSUBW", LTYPEY, APSUBW, + "VPUNPCKHBW", LTYPEY, APUNPCKHBW, + "VPUNPCKHLQ", LTYPEY, APUNPCKHLQ, + "VPUNPCKHQDQ", LTYPEY, APUNPCKHQDQ, + "VPUNPCKHWL", LTYPEY, APUNPCKHWL, + "VPUNPCKLBW", LTYPEY, APUNPCKLBW, + "VPUNPCKLLQ", LTYPEY, APUNPCKLLQ, + "VPUNPCKLQDQ", LTYPEY, APUNPCKLQDQ, + "VPUNPCKLWL", LTYPEY, APUNPCKLWL, + "VPXOR", LTYPEY, APXOR, + "VRCPPS", LTYPEY, ARCPPS, + "VRCPSS", LTYPEY, ARCPSS, + "VRSQRTPS", LTYPEY, ARSQRTPS, + "VRSQRTSS", LTYPEY, ARSQRTSS, + "VSHUFPD", LTYPEX, ASHUFPD, + "VSHUFPS", LTYPEX, ASHUFPS, + "VSQRTPD", LTYPEY, ASQRTPD, + "VSQRTPS", LTYPEY, ASQRTPS, + "VSQRTSD", LTYPEY, ASQRTSD, + "VSQRTSS", LTYPEY, ASQRTSS, + "VSTMXCSR", LTYPE1, ASTMXCSR, + "VSUBPD", LTYPEY, ASUBPD, + "VSUBPS", LTYPEY, ASUBPS, + "VSUBSD", LTYPEY, ASUBSD, + "VSUBSS", LTYPEY, ASUBSS, + "VUCOMISD", LTYPEY, AUCOMISD, + "VUCOMISS", LTYPEY, AUCOMISS, + "VUNPCKHPD", LTYPEY, AUNPCKHPD, + "VUNPCKHPS", LTYPEY, AUNPCKHPS, + "VUNPCKLPD", LTYPEY, AUNPCKLPD, + "VUNPCKLPS", LTYPEY, AUNPCKLPS, + "VXORPD", LTYPEY, AXORPD, + "VXORPS", LTYPEY, AXORPS, + "VAESDEC", LTYPEY, AAESDEC, + "VAESDECLAST", LTYPEY, AAESDECLAST, + "VAESENC", LTYPEY, AAESENC, + "VAESENCLAST", LTYPEY, AAESENCLAST, + "VAESIMC", LTYPEY, AAESIMC, + "VAESKEYGENASSIST", LTYPEY, AAESKEYGENASSIST, + "VBLENDPD", LTYPEY, ABLENDPD, + "VBLENDPS", LTYPEY, ABLENDPS, + "VBLENDVPD", LTYPEY, ABLENDVPD, + "VBLENDVPS", LTYPEY, ABLENDVPS, + "VDPPD", LTYPEY, ADPPD, + "VDPPS", LTYPEY, ADPPS, + "VEXTRACTPS", LTYPEY, AEXTRACTPS, + "VINSERTPS", LTYPEY, AINSERTPS, + "VMOVNTDQA", LTYPEY, AMOVNTDQA, + "VMPSADBW", LTYPEY, AMPSADBW, + "VPABSB", LTYPEY, APABSB, + "VPABSD", LTYPEY, APABSL, /* syn */ + "VPABSL", LTYPEY, APABSL, + "VPABSW", LTYPEY, APABSW, + "VPACKUSDW", LTYPEY, APACKUSDW, + "VPALIGNR", LTYPEX, APALIGNR, + "VPBLENDVB", LTYPEY, APBLENDVB, + "VPBLENDW", LTYPEY, APBLENDW, + "VPCLMULHQHQDQ", LTYPEY, APCLMULHQHQDQ, + "VPCLMULHQLQDQ", LTYPEY, APCLMULHQLQDQ, + "VPCLMULLQHQDQ", LTYPEY, APCLMULLQHQDQ, + "VPCLMULLQLQDQ", LTYPEY, APCLMULLQLQDQ, + "VPCLMULQDQ", LTYPEY, APCLMULQDQ, + "VPCMPEQQ", LTYPEY, APCMPEQQ, + "VPCMPESTRI", LTYPEY, APCMPESTRI, + "VPCMPESTRM", LTYPEY, APCMPESTRM, + "VPCMPGTQ", LTYPEY, APCMPGTQ, + "VPCMPISTRI", LTYPEY, APCMPISTRI, + "VPCMPISTRM", LTYPEY, APCMPISTRM, + "VPEXTRB", LTYPEY, APEXTRB, + "VPEXTRL", LTYPEY, APEXTRL, + "VPHADDL", LTYPEY, APHADDL, + "VPHADDSW", LTYPEY, APHADDSW, + "VPHADDW", LTYPEY, APHADDW, + "VPHMINPOSUW", LTYPEY, APHMINPOSUW, + "VPHSUBL", LTYPEY, APHSUBL, + "VPHSUBSW", LTYPEY, APHSUBSW, + "VPHSUBW", LTYPEY, APHSUBW, + "VPINSRB", LTYPEY, APINSRB, + "VPINSRL", LTYPEY, APINSRL, + "VPMADDUBSW", LTYPEY, APMADDUBSW, + "VPMAXSB", LTYPEY, APMAXSB, + "VPMAXSL", LTYPEY, APMAXSL, + "VPMAXUL", LTYPEY, APMAXUL, + "VPMAXUW", LTYPEY, APMAXUW, + "VPMINSB", LTYPEY, APMINSB, + "VPMINSL", LTYPEY, APMINSL, + "VPMINUL", LTYPEY, APMINUL, + "VPMINUW", LTYPEY, APMINUW, + "VPMOVSXBL", LTYPEY, APMOVSXBL, + "VPMOVSXBQ", LTYPEY, APMOVSXBQ, + "VPMOVSXBW", LTYPEY, APMOVSXBW, + "VPMOVSXLQ", LTYPEY, APMOVSXLQ, + "VPMOVSXWL", LTYPEY, APMOVSXWL, + "VPMOVSXWQ", LTYPEY, APMOVSXWQ, + "VPMOVZXBL", LTYPEY, APMOVZXBL, + "VPMOVZXBQ", LTYPEY, APMOVZXBQ, + "VPMOVZXBW", LTYPEY, APMOVZXBW, + "VPMOVZXLQ", LTYPEY, APMOVZXLQ, + "VPMOVZXWL", LTYPEY, APMOVZXWL, + "VPMOVZXWQ", LTYPEY, APMOVZXWQ, + "VPMULHRSW", LTYPEY, APMULHRSW, + "VPMULLL", LTYPEY, APMULLL, + "VPMULLQ", LTYPEY, APMULLQ, + "VPSHUFB", LTYPEY, APSHUFB, + "VPSIGNB", LTYPEY, APSIGNB, + "VPSIGNL", LTYPEY, APSIGNL, + "VPSIGNW", LTYPEY, APSIGNW, + "VPTEST", LTYPEY, APTEST, + "VROUNDPD", LTYPEY, AROUNDPD, + "VROUNDPS", LTYPEY, AROUNDPS, + "VROUNDSD", LTYPEY, AROUNDSD, + "VROUNDSS", LTYPEY, AROUNDSS, 0 }; +int +isxyreg(int t) +{ + return t >= D_X0 && t <= D_X15 || t >= D_Y0 && t <= D_Y15; +} + void cinit(void) { @@ -1066,8 +1454,7 @@ void zaddr(Gen *a, int s) { - long l; - int i, t; + int i, l, t; char *n; Ieee e; diff -Nru /n/sources/plan9/sys/src/cmd/6c/6.out.h /sys/src/cmd/6c/6.out.h --- /n/sources/plan9/sys/src/cmd/6c/6.out.h Mon May 23 18:57:57 2005 +++ /sys/src/cmd/6c/6.out.h Mon Dec 14 00:00:00 2015 @@ -535,7 +535,7 @@ AFXSAVE, AFXSAVE64, ALDMXCSR, - AMASKMOVOU, + AMASKMOVDQU, AMASKMOVQ, AMAXPD, AMAXPS, @@ -547,7 +547,7 @@ AMINSS, AMOVAPD, AMOVAPS, - AMOVOU, + AMOVDQU, AMOVHLPS, AMOVHPD, AMOVHPS, @@ -556,7 +556,7 @@ AMOVLPS, AMOVMSKPD, AMOVMSKPS, - AMOVNTO, + AMOVNTDQ, AMOVNTPD, AMOVNTPS, AMOVNTQ, @@ -636,13 +636,13 @@ APSHUFL, APSHUFLW, APSHUFW, - APSLLO, + APSLLDQ, APSLLL, APSLLQ, APSLLW, APSRAL, APSRAW, - APSRLO, + APSRLDQ, APSRLL, APSRLQ, APSRLW, @@ -699,6 +699,119 @@ AMODE, + AMOVQQA, + AMOVQQU, + ABSWAPL, + ABSWAPQ, + + /* more sse/vex */ + AAESDEC, + AAESDECLAST, + AAESENC, + AAESENCLAST, + AAESIMC, + AAESKEYGENASSIST, + ABLENDPD, + ABLENDPS, + ABLENDVPD, + ABLENDVPS, + ACRC32L, + ADPPD, + ADPPS, + AEXTRACTPS, + AINSERTPS, + AMOVNTDQA, + AMPSADBW, + APABSB, + APABSL, + APABSW, + APACKUSDW, + APALIGNR, + APBLENDVB, + APBLENDW, + APCLMULHQHQDQ, + APCLMULHQLQDQ, + APCLMULLQHQDQ, + APCLMULLQLQDQ, + APCLMULQDQ, + APCMPEQQ, + APCMPESTRI, + APCMPESTRM, + APCMPGTQ, + APCMPISTRI, + APCMPISTRM, + APEXTRB, + APEXTRL, + APHADDL, + APHADDSW, + APHADDW, + APHMINPOSUW, + APHSUBL, + APHSUBSW, + APHSUBW, + APINSRB, + APINSRL, + APMADDUBSW, + APMAXSB, + APMAXSL, + APMAXUL, + APMAXUW, + APMINSB, + APMINSL, + APMINUL, + APMINUW, + APMOVSXBL, + APMOVSXBQ, + APMOVSXBW, + APMOVSXLQ, + APMOVSXWL, + APMOVSXWQ, + APMOVZXBL, + APMOVZXBQ, + APMOVZXBW, + APMOVZXLQ, + APMOVZXWL, + APMOVZXWQ, + APMULHRSW, + APMULLL, + APMULLQ, + APSHUFB, + APSIGNB, + APSIGNL, + APSIGNW, + APTEST, + AROUNDPD, + AROUNDPS, + AROUNDSD, + AROUNDSS, + AVBROADCASTF128, + AVBROADCASTSL, + AVBROADCASTSS, + AVMASKMOVPD, + AVMASKMOVPS, + AVPERMILPD, + AVPERMILPS, + AVTESTPD, + AVTESTPS, + AXSAVE, + AXSAVEOPT, + AXRSTOR, + ACRC32B, + ACRC32W, + ARDRANDW, + ARDRANDL, + ACRC32Q, + APEXTRQ, + APINSRQ, + ARDRANDQ, + AMOVDQA, + APOPCNTW, + APOPCNTL, + APOPCNTQ, + AMOVQL, + APAUSE, + ACMPXCHG16B, + ALAST }; @@ -744,11 +857,11 @@ D_DH, D_BH, - D_F0 = 36, - - D_M0 = 44, + D_Y0 = 36, + D_Y15 = D_Y0+15, D_X0 = 52, + D_X15 = D_X0+15, D_CS = 68, D_SS, @@ -783,6 +896,14 @@ D_FILE1, D_INDIR, /* additive */ + D_CONST2 = D_INDIR+D_INDIR, + D_SIZE, + + D_M0, + D_M7 = D_M0+7, + D_F0 = D_M0, + D_F7 = D_F0+7, + D_XREG, T_TYPE = 1<<0, T_INDEX = 1<<1, diff -Nru /n/sources/plan9/sys/src/cmd/6c/cgen.c /sys/src/cmd/6c/cgen.c --- /n/sources/plan9/sys/src/cmd/6c/cgen.c Thu Feb 28 19:10:56 2013 +++ /sys/src/cmd/6c/cgen.c Mon Dec 14 00:00:00 2015 @@ -2,7 +2,6 @@ /* ,x/^(print|prtree)\(/i/\/\/ */ int castup(Type*, Type*); -void checkmask(Node*, Node*); void cgen(Node *n, Node *nn) @@ -258,8 +257,6 @@ break; } } - if(n->op == OAND) - checkmask(n, r); if(r->addable >= INDEXED && !hardconst(r)) { regalloc(&nod, l, nn); cgen(l, &nod); @@ -475,8 +472,6 @@ goto asand; if(l->op == OBIT) goto asbitop; - if(typefd[n->type->etype]) - goto asand; /* can this happen? */ /* * get nod to be D_CX @@ -524,8 +519,6 @@ goto asbitop; if(typefd[l->type->etype] || typefd[r->type->etype]) goto asfop; - if(o == OASAND) - checkmask(n, r); if(l->complex >= r->complex) { if(hardleft) reglcgen(&nod, l, Z); @@ -1866,22 +1859,6 @@ return ft == TULONG || ft == TUINT || ft == TUSHORT; } return 0; -} - -/* - * vl &= ~ul or vl & ~ul - * create a ul mask with top bits zero, which is usually wrong - */ -void -checkmask(Node *n, Node *r) -{ - Node *rl; - - if((n->op == OAND || n->op == OASAND) && - r->op == OCAST && - (rl = r->left)->op == OCOM && - typesuv[n->type->etype] && typeu[rl->type->etype] && typechl[rl->type->etype]) - warn(n, "32-bit mask zero-extended to 64 bits"); } void diff -Nru /n/sources/plan9/sys/src/cmd/6c/enam.c /sys/src/cmd/6c/enam.c --- /n/sources/plan9/sys/src/cmd/6c/enam.c Mon May 23 18:57:57 2005 +++ /sys/src/cmd/6c/enam.c Mon Dec 14 00:00:00 2015 @@ -504,7 +504,7 @@ "FXSAVE", "FXSAVE64", "LDMXCSR", - "MASKMOVOU", + "MASKMOVDQU", "MASKMOVQ", "MAXPD", "MAXPS", @@ -516,7 +516,7 @@ "MINSS", "MOVAPD", "MOVAPS", - "MOVOU", + "MOVDQU", "MOVHLPS", "MOVHPD", "MOVHPS", @@ -525,7 +525,7 @@ "MOVLPS", "MOVMSKPD", "MOVMSKPS", - "MOVNTO", + "MOVNTDQ", "MOVNTPD", "MOVNTPS", "MOVNTQ", @@ -605,13 +605,13 @@ "PSHUFL", "PSHUFLW", "PSHUFW", - "PSLLO", + "PSLLDQ", "PSLLL", "PSLLQ", "PSLLW", "PSRAL", "PSRAW", - "PSRLO", + "PSRLDQ", "PSRLL", "PSRLQ", "PSRLW", @@ -665,5 +665,115 @@ "RETFQ", "SWAPGS", "MODE", + "MOVQQA", + "MOVQQU", + "BSWAPL", + "BSWAPQ", + "AESDEC", + "AESDECLAST", + "AESENC", + "AESENCLAST", + "AESIMC", + "AESKEYGENASSIST", + "BLENDPD", + "BLENDPS", + "BLENDVPD", + "BLENDVPS", + "CRC32L", + "DPPD", + "DPPS", + "EXTRACTPS", + "INSERTPS", + "MOVNTDQA", + "MPSADBW", + "PABSB", + "PABSL", + "PABSW", + "PACKUSDW", + "PALIGNR", + "PBLENDVB", + "PBLENDW", + "PCLMULHQHQDQ", + "PCLMULHQLQDQ", + "PCLMULLQHQDQ", + "PCLMULLQLQDQ", + "PCLMULQDQ", + "PCMPEQQ", + "PCMPESTRI", + "PCMPESTRM", + "PCMPGTQ", + "PCMPISTRI", + "PCMPISTRM", + "PEXTRB", + "PEXTRL", + "PHADDL", + "PHADDSW", + "PHADDW", + "PHMINPOSUW", + "PHSUBL", + "PHSUBSW", + "PHSUBW", + "PINSRB", + "PINSRL", + "PMADDUBSW", + "PMAXSB", + "PMAXSL", + "PMAXUL", + "PMAXUW", + "PMINSB", + "PMINSL", + "PMINUL", + "PMINUW", + "PMOVSXBL", + "PMOVSXBQ", + "PMOVSXBW", + "PMOVSXLQ", + "PMOVSXWL", + "PMOVSXWQ", + "PMOVZXBL", + "PMOVZXBQ", + "PMOVZXBW", + "PMOVZXLQ", + "PMOVZXWL", + "PMOVZXWQ", + "PMULHRSW", + "PMULLL", + "PMULLQ", + "PSHUFB", + "PSIGNB", + "PSIGNL", + "PSIGNW", + "PTEST", + "ROUNDPD", + "ROUNDPS", + "ROUNDSD", + "ROUNDSS", + "VBROADCASTF128", + "VBROADCASTSL", + "VBROADCASTSS", + "VMASKMOVPD", + "VMASKMOVPS", + "VPERMILPD", + "VPERMILPS", + "VTESTPD", + "VTESTPS", + "XSAVE", + "XSAVEOPT", + "XRSTOR", + "CRC32B", + "CRC32W", + "RDRANDW", + "RDRANDL", + "CRC32Q", + "PEXTRQ", + "PINSRQ", + "RDRANDQ", + "MOVDQA", + "POPCNTW", + "POPCNTL", + "POPCNTQ", + "MOVQL", + "PAUSE", + "CMPXCHG16B", "LAST", }; diff -Nru /n/sources/plan9/sys/src/cmd/6c/gc.h /sys/src/cmd/6c/gc.h --- /n/sources/plan9/sys/src/cmd/6c/gc.h Mon Mar 4 21:15:20 2013 +++ /sys/src/cmd/6c/gc.h Mon Dec 14 00:00:00 2015 @@ -122,7 +122,7 @@ Node* scope; }; -#define NRGN 600 +#define NRGN 1000 struct Rgn { Reg* enter; @@ -157,7 +157,7 @@ EXTERN Sym* symrathole; EXTERN Node znode; EXTERN Prog zprog; -EXTERN int reg[D_NONE]; +EXTERN int reg[D_XREG]; EXTERN long exregoffset; EXTERN long exfregoffset; EXTERN uchar typechlpv[NTYPE]; @@ -334,9 +334,6 @@ long FtoB(int); int BtoR(long); int BtoF(long); - -#define D_HI D_NONE -#define D_LO D_NONE #define isregtype(t) ((t)>= D_AX && (t)<=D_R15) diff -Nru /n/sources/plan9/sys/src/cmd/6c/list.c /sys/src/cmd/6c/list.c --- /n/sources/plan9/sys/src/cmd/6c/list.c Mon May 23 18:57:57 2005 +++ /sys/src/cmd/6c/list.c Mon Dec 14 00:00:00 2015 @@ -47,13 +47,13 @@ p = va_arg(fp->args, Prog*); if(p->as == ADATA) - sprint(str, " %A %D/%d,%D", + snprint(str, sizeof(str), " %A %D/%d,%D", p->as, &p->from, p->from.scale, &p->to); else if(p->as == ATEXT) - sprint(str, " %A %D,%d,%D", + snprint(str, sizeof(str), " %A %D,%d,%D", p->as, &p->from, p->from.scale, &p->to); else - sprint(str, " %A %D,%D", + snprint(str, sizeof(str), " %A %D,%D", p->as, &p->from, &p->to); return fmtstrcpy(fp, str); } @@ -76,20 +76,20 @@ a = va_arg(fp->args, Adr*); i = a->type; - if(i >= D_INDIR) { + if(i >= D_INDIR && i < D_CONST2) { if(a->offset) - sprint(str, "%lld(%R)", a->offset, i-D_INDIR); + snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR); else - sprint(str, "(%R)", i-D_INDIR); + snprint(str, sizeof(str), "(%R)", i-D_INDIR); goto brk; } switch(i) { default: if(a->offset) - sprint(str, "$%lld,%R", a->offset, i); + snprint(str, sizeof(str), "$%lld,%R", a->offset, i); else - sprint(str, "%R", i); + snprint(str, sizeof(str), "%R", i); break; case D_NONE: @@ -97,53 +97,54 @@ break; case D_BRANCH: - sprint(str, "%lld(PC)", a->offset-pc); + snprint(str, sizeof(str), "%lld(PC)", a->offset-pc); break; case D_EXTERN: - sprint(str, "%s+%lld(SB)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%lld(SB)", a->sym->name, a->offset); break; case D_STATIC: - sprint(str, "%s<>+%lld(SB)", a->sym->name, + snprint(str, sizeof(str), "%s<>+%lld(SB)", a->sym->name, a->offset); break; case D_AUTO: - sprint(str, "%s+%lld(SP)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%lld(SP)", a->sym->name, a->offset); break; case D_PARAM: if(a->sym) - sprint(str, "%s+%lld(FP)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%lld(FP)", a->sym->name, a->offset); else - sprint(str, "%lld(FP)", a->offset); + snprint(str, sizeof(str), "%lld(FP)", a->offset); break; case D_CONST: - sprint(str, "$%lld", a->offset); + snprint(str, sizeof(str), "$%lld", a->offset); break; case D_FCONST: - sprint(str, "$(%.17e)", a->dval); + snprint(str, sizeof(str), "$(%.17e)", a->dval); break; case D_SCONST: - sprint(str, "$\"%S\"", a->sval); + snprint(str, sizeof(str), "$\"%S\"", a->sval); break; case D_ADDR: a->type = a->index; a->index = D_NONE; - sprint(str, "$%D", a); + snprint(str, sizeof(str), "$%D", a); a->index = a->type; a->type = D_ADDR; goto conv; } brk: if(a->index != D_NONE) { - sprint(s, "(%R*%d)", (int)a->index, (int)a->scale); - strcat(str, s); + fmtstrcpy(fp, str); + snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale); + return fmtstrcpy(fp, s); } conv: return fmtstrcpy(fp, str); @@ -190,23 +191,23 @@ "DH", "BH", - "F0", /* [D_F0] */ - "F1", - "F2", - "F3", - "F4", - "F5", - "F6", - "F7", - - "M0", - "M1", - "M2", - "M3", - "M4", - "M5", - "M6", - "M7", + "Y0", /* [D_Y0] */ + "Y1", + "Y2", + "Y3", + "Y4", + "Y5", + "Y6", + "Y7", + + "Y8", + "Y9", + "Y10", + "Y11", + "Y12", + "Y13", + "Y14", + "Y15", "X0", "X1", @@ -284,9 +285,13 @@ r = va_arg(fp->args, int); if(r >= D_AL && r <= D_NONE) - sprint(str, "%s", regstr[r-D_AL]); + snprint(str, sizeof(str), "%s", regstr[r-D_AL]); + else if(r >= D_Y0 && r <= D_Y15) + snprint(str, sizeof(str), "Y%d", r-D_Y0); + else if(r >= D_M0 && r <= D_M7) + snprint(str, sizeof(str), "M%d", r-D_M0); else - sprint(str, "gok(%d)", r); + snprint(str, sizeof(str), "gok(%d)", r); return fmtstrcpy(fp, str); } diff -Nru /n/sources/plan9/sys/src/cmd/6c/mul.c /sys/src/cmd/6c/mul.c --- /n/sources/plan9/sys/src/cmd/6c/mul.c Mon May 23 18:57:57 2005 +++ /sys/src/cmd/6c/mul.c Mon Dec 14 00:00:00 2015 @@ -312,6 +312,11 @@ Mparam *p; Node nod, nods; + if(v == 0){ + zeroregm(n); + return 1; + } + for(i = 0; i < nelem(multab); i++) { p = &multab[i]; if(p->value == v) diff -Nru /n/sources/plan9/sys/src/cmd/6c/peep.c /sys/src/cmd/6c/peep.c --- /n/sources/plan9/sys/src/cmd/6c/peep.c Wed Dec 28 20:52:06 2005 +++ /sys/src/cmd/6c/peep.c Mon Dec 14 00:00:00 2015 @@ -117,6 +117,7 @@ case AMOVWLZX: case AMOVBLSX: case AMOVWLSX: + case AMOVQL: if(regtyp(&p->to)) { r1 = rnops(uniqs(r)); if(r1 != R) { @@ -347,8 +348,13 @@ case ACDQ: case ACQO: + case ASTOSB: + case ASTOSL: + case ASTOSQ: + case AMOVSB: case AMOVSL: case AMOVSQ: + case AMOVQL: return 0; case AMOVL: @@ -547,6 +553,7 @@ case AMOVWLZX: case AMOVWQSX: case AMOVWQZX: + case AMOVQL: case AMOVSS: case AMOVSD: @@ -725,11 +732,23 @@ return 2; goto caseread; - case AMOVSL: - case AMOVSQ: case AREP: case AREPN: - if(v->type == D_CX || v->type == D_DI || v->type == D_SI) + if(v->type == D_CX) + return 2; + goto caseread; + + case AMOVSB: + case AMOVSL: + case AMOVSQ: + if(v->type == D_DI || v->type == D_SI) + return 2; + goto caseread; + + case ASTOSB: + case ASTOSL: + case ASTOSQ: + if(v->type == D_AX || v->type == D_DI) return 2; goto caseread; diff -Nru /n/sources/plan9/sys/src/cmd/6c/reg.c /sys/src/cmd/6c/reg.c --- /n/sources/plan9/sys/src/cmd/6c/reg.c Mon Sep 17 18:58:11 2012 +++ /sys/src/cmd/6c/reg.c Mon Dec 14 00:00:00 2015 @@ -183,6 +183,7 @@ case AMOVWLZX: case AMOVWQSX: case AMOVWQZX: + case AMOVQL: case AMOVSS: case AMOVSD: @@ -731,6 +732,7 @@ r->regu |= doregbits(t); r->regu |= doregbits(a->index); + s = a->sym; switch(t) { default: goto none; @@ -743,12 +745,13 @@ goto none; case D_EXTERN: case D_STATIC: + if(s->type != nil && s->type->garb & GVOLATILE) + goto none; case D_PARAM: case D_AUTO: n = t; break; } - s = a->sym; if(s == S) goto none; if(s->name[0] == '.') diff -Nru /n/sources/plan9/sys/src/cmd/6c/txt.c /sys/src/cmd/6c/txt.c --- /n/sources/plan9/sys/src/cmd/6c/txt.c Mon Sep 17 18:58:11 2012 +++ /sys/src/cmd/6c/txt.c Mon Dec 14 00:00:00 2015 @@ -93,9 +93,6 @@ nodret = new(OIND, nodret, Z); complex(nodret); - if(0) - com64init(); - memset(reg, 0, sizeof(reg)); for(i=0; iop == OCONST) + if(f->vconst > 0x7fffffffLL || f->vconst < -0x7fffffffLL) + if(t->op != OREGISTER) { + regalloc(&nod, f, Z); + gmove(f, &nod); + gmove(&nod, t); + regfree(&nod); + return; + } + if(f->op == ONAME || f->op == OINDREG || f->op == OIND || f->op == OINDEX) switch(ft) { @@ -665,6 +673,7 @@ a = AMOVLQZX; /* could probably use plain MOVL */ goto ld; case TVLONG: + case TUVLONG: if(typefd[tt]) { regalloc(&nod, t, t); if(tt == TDOUBLE) @@ -676,7 +685,6 @@ regfree(&nod); return; } - case TUVLONG: a = AMOVQ; goto ld; case TIND: @@ -767,7 +775,6 @@ case CASE( TUINT, TCHAR): case CASE( TLONG, TCHAR): case CASE( TULONG, TCHAR): - case CASE( TIND, TCHAR): case CASE( TCHAR, TUCHAR): case CASE( TUCHAR, TUCHAR): @@ -777,7 +784,6 @@ case CASE( TUINT, TUCHAR): case CASE( TLONG, TUCHAR): case CASE( TULONG, TUCHAR): - case CASE( TIND, TUCHAR): case CASE( TSHORT, TSHORT): case CASE( TUSHORT,TSHORT): @@ -785,7 +791,6 @@ case CASE( TUINT, TSHORT): case CASE( TLONG, TSHORT): case CASE( TULONG, TSHORT): - case CASE( TIND, TSHORT): case CASE( TSHORT, TUSHORT): case CASE( TUSHORT,TUSHORT): @@ -793,42 +798,26 @@ case CASE( TUINT, TUSHORT): case CASE( TLONG, TUSHORT): case CASE( TULONG, TUSHORT): - case CASE( TIND, TUSHORT): case CASE( TINT, TINT): case CASE( TUINT, TINT): case CASE( TLONG, TINT): case CASE( TULONG, TINT): - case CASE( TIND, TINT): case CASE( TINT, TUINT): case CASE( TUINT, TUINT): case CASE( TLONG, TUINT): case CASE( TULONG, TUINT): - case CASE( TIND, TUINT): - - case CASE( TUINT, TIND): - case CASE( TVLONG, TUINT): - case CASE( TVLONG, TULONG): - case CASE( TUVLONG, TUINT): - case CASE( TUVLONG, TULONG): *****/ a = AMOVL; break; - case CASE( TVLONG, TCHAR): - case CASE( TVLONG, TSHORT): - case CASE( TVLONG, TINT): - case CASE( TVLONG, TLONG): - case CASE( TUVLONG, TCHAR): - case CASE( TUVLONG, TSHORT): - case CASE( TUVLONG, TINT): - case CASE( TUVLONG, TLONG): + case CASE( TINT, TIND): case CASE( TINT, TVLONG): case CASE( TINT, TUVLONG): - case CASE( TLONG, TVLONG): - case CASE( TINT, TIND): case CASE( TLONG, TIND): + case CASE( TLONG, TVLONG): + case CASE( TLONG, TUVLONG): a = AMOVLQSX; if(f->op == OCONST) { f->vconst &= (uvlong)0xffffffffU; @@ -844,22 +833,53 @@ case CASE( TULONG, TVLONG): case CASE( TULONG, TUVLONG): case CASE( TULONG, TIND): - a = AMOVL; /* same effect as AMOVLQZX */ + a = AMOVLQZX; if(f->op == OCONST) { f->vconst &= (uvlong)0xffffffffU; a = AMOVQ; } break; + + case CASE( TIND, TCHAR): + case CASE( TIND, TUCHAR): + case CASE( TIND, TSHORT): + case CASE( TIND, TUSHORT): + case CASE( TIND, TINT): + case CASE( TIND, TUINT): + case CASE( TIND, TLONG): + case CASE( TIND, TULONG): + case CASE( TVLONG, TCHAR): + case CASE( TVLONG, TUCHAR): + case CASE( TVLONG, TSHORT): + case CASE( TVLONG, TUSHORT): + case CASE( TVLONG, TINT): + case CASE( TVLONG, TUINT): + case CASE( TVLONG, TLONG): + case CASE( TVLONG, TULONG): + case CASE( TUVLONG, TCHAR): + case CASE( TUVLONG, TUCHAR): + case CASE( TUVLONG, TSHORT): + case CASE( TUVLONG, TUSHORT): + case CASE( TUVLONG, TINT): + case CASE( TUVLONG, TUINT): + case CASE( TUVLONG, TLONG): + case CASE( TUVLONG, TULONG): + a = AMOVQL; + if(f->op == OCONST) { + f->vconst &= 0xffffffffU; + a = AMOVL; + } + break; + case CASE( TIND, TIND): case CASE( TIND, TVLONG): - case CASE( TVLONG, TVLONG): - case CASE( TUVLONG, TVLONG): - case CASE( TVLONG, TUVLONG): - case CASE( TUVLONG, TUVLONG): case CASE( TIND, TUVLONG): case CASE( TVLONG, TIND): + case CASE( TVLONG, TVLONG): + case CASE( TVLONG, TUVLONG): case CASE( TUVLONG, TIND): - case CASE( TIND, TIND): + case CASE( TUVLONG, TVLONG): + case CASE( TUVLONG, TUVLONG): a = AMOVQ; break; @@ -1007,7 +1027,7 @@ return; /* - * ulong to float + * uvlong to float */ case CASE( TUVLONG, TDOUBLE): case CASE( TUVLONG, TFLOAT): diff -Nru /n/sources/plan9/sys/src/cmd/6l/asm.c /sys/src/cmd/6l/asm.c --- /n/sources/plan9/sys/src/cmd/6l/asm.c Tue Mar 26 23:17:32 2013 +++ /sys/src/cmd/6l/asm.c Mon Dec 14 00:00:00 2015 @@ -28,7 +28,8 @@ return s->value; } -/* these need to take long arguments to be compatible with elf.c */void +/* these need to take long arguments to be compatible with elf.c */ +void wputl(long w) { cput(w); diff -Nru /n/sources/plan9/sys/src/cmd/6l/compat.c /sys/src/cmd/6l/compat.c --- /n/sources/plan9/sys/src/cmd/6l/compat.c Mon Dec 17 19:33:08 2012 +++ /sys/src/cmd/6l/compat.c Mon Dec 14 00:00:00 2015 @@ -50,8 +50,10 @@ } void -setmalloctag(void*, ulong) +setmalloctag(void *v, ulong pc) { + USED(v); + USED(pc); } int diff -Nru /n/sources/plan9/sys/src/cmd/6l/l.h /sys/src/cmd/6l/l.h --- /n/sources/plan9/sys/src/cmd/6l/l.h Tue Mar 26 23:18:09 2013 +++ /sys/src/cmd/6l/l.h Mon Dec 14 00:00:00 2015 @@ -2,7 +2,7 @@ #include #include #include "../6c/6.out.h" -#include "../8l/elf.h" +#include "../ld/elf.h" #ifndef EXTERN #define EXTERN extern @@ -17,7 +17,6 @@ cflush(); } #define LIBNAMELEN 300 - typedef struct Adr Adr; typedef struct Prog Prog; typedef struct Sym Sym; @@ -92,7 +91,7 @@ { short as; uchar* ytab; - uchar prefix; + ushort prefix; uchar op[20]; }; struct Movtab @@ -155,8 +154,8 @@ Ycr0, Ycr1, Ycr2, Ycr3, Ycr4, Ycr5, Ycr6, Ycr7, Ycr8, Ydr0, Ydr1, Ydr2, Ydr3, Ydr4, Ydr5, Ydr6, Ydr7, Ytr0, Ytr1, Ytr2, Ytr3, Ytr4, Ytr5, Ytr6, Ytr7, Yrl32, Yrl64, - Ymr, Ymm, - Yxr, Yxm, + Ymr, Ymm, + Yxr, Yxm, Yyr, Yxyr, Ymax, Zxxx = 0, @@ -212,9 +211,13 @@ Pb = 0xfe, /* byte operands */ Pf2 = 0xf2, /* xmm escape 1 */ Pf3 = 0xf3, /* xmm escape 2 */ + Pm38 = 0x38, /* 0f.38 opcode */ + Pm3a = 0x3a, /* 0f.3a opcode */ Pw = 0x48, /* Rex.w */ Py = 0x80, /* defaults to 64-bit mode */ + P2 = 1<<9, /* flag: two operand (avx only) */ + Rxf = 1<<9, /* internal flag for Rxr on from */ Rxt = 1<<8, /* internal flag for Rxr on to */ Rxw = 1<<3, /* =1, 64-bit operand size */ @@ -222,6 +225,26 @@ Rxx = 1<<1, /* extend sib index */ Rxb = 1<<0, /* extend modrm r/m, sib base, or opcode reg */ + Vex2 = 0xc5, /* 2-byte vex prefix */ + Vex3 = 0xc4, /* 3-byte vex prefix */ + + /* vex flags */ + Vexr = 1<<7, /* byte 1, both */ + Vexx = 1<<6, /* byte 1, 3-byte */ + Vexb = 1<<5, /* byte 1, 3-byte */ + Vexw = 1<<7, /* byte 2, 3-byte */ + Vexl = 1<<2, /* 256-bit vector */ + + Vexnr = 0xF<<3, /* no reg */ + Vexp0 = 0, /* no SIMD prefix */ + Vexp66 = 1, /* prefix 66 */ + Vexpf3 = 2, /* prefix f3 */ + Vexpf2 = 3, /* prefix f2 */ + + Vex0f = 1, /* 0F opcode byte */ + Vex0f38 = 2, /* 0F 38 opcode bytes */ + Vex0f3a = 3, /* 0F 3A opcode bytes */ + Roffset = 22, /* no. bits for offset in relocation address */ Rindex = 10, /* no. bits for index in relocation address */ }; @@ -244,6 +267,7 @@ #pragma varargck type "D" Adr* #pragma varargck type "P" Prog* #pragma varargck type "R" int +#pragma varargck type "R" uint #pragma varargck type "S" char* #pragma varargck argpos diag 1 @@ -291,8 +315,8 @@ EXTERN uchar* andptr; EXTERN uchar* rexptr; EXTERN uchar and[30]; -EXTERN int reg[D_NONE]; -EXTERN int regrex[D_NONE+1]; +EXTERN int reg[D_XREG]; +EXTERN int regrex[D_XREG+1]; EXTERN Prog* lastp; EXTERN long lcsize; EXTERN int nerrors; @@ -308,6 +332,7 @@ EXTERN vlong textsize; EXTERN long thunk; EXTERN int version; +EXTERN int vexed; EXTERN Prog zprg; EXTERN int dtype; EXTERN char* paramspace; @@ -315,7 +340,7 @@ EXTERN Adr* reloca; EXTERN int doexp, dlm; EXTERN int imports, nimports; -EXTERN int exports, nexports; +EXTERN int exports, nexports, allexport; EXTERN char* EXPTAB; EXTERN Prog undefp; @@ -368,12 +393,13 @@ double ieeedtod(Ieee*); long ieeedtof(Ieee*); void import(void); +int isxyreg(int); void ldobj(int, long, char*); void loadlib(void); void listinit(void); -Sym* lookup(char*, int); void llput(vlong v); void llputl(vlong v); +Sym* lookup(char*, int); void lput(long); void lputl(long); void main(int, char*[]); diff -Nru /n/sources/plan9/sys/src/cmd/6l/list.c /sys/src/cmd/6l/list.c --- /n/sources/plan9/sys/src/cmd/6l/list.c Mon May 23 18:57:48 2005 +++ /sys/src/cmd/6l/list.c Mon Dec 14 00:00:00 2015 @@ -24,18 +24,25 @@ switch(p->as) { case ATEXT: if(p->from.scale) { - sprint(str, "(%ld) %A %D,%d,%D", + snprint(str, sizeof(str), "(%ld) %A %D,%d,%D", p->line, p->as, &p->from, p->from.scale, &p->to); break; } default: - sprint(str, "(%ld) %A %D,%D", - p->line, p->as, &p->from, &p->to); + if(isxyreg(p->to.type) && p->to.index != D_NONE) + snprint(str, sizeof(str), "(%ld) V%A %D,%R,%R", + p->line, p->as, &p->from, p->to.index, p->to.type); + else if(isxyreg(p->from.type) && p->from.index != D_NONE) + snprint(str, sizeof(str), "(%ld) V%A %R,%R,%D", + p->line, p->as, p->from.type, p->from.index, &p->to); + else + snprint(str, sizeof(str), "(%ld) %A %D,%D", + p->line, p->as, &p->from, &p->to); break; case ADATA: case AINIT: case ADYNT: - sprint(str, "(%ld) %A %D/%d,%D", + snprint(str, sizeof(str), "(%ld) %A %D/%d,%D", p->line, p->as, &p->from, p->from.scale, &p->to); break; } @@ -55,26 +62,26 @@ int Dconv(Fmt *fp) { - char str[40], s[20]; + char str[STRINGSZ+40], s[20]; Adr *a; int i; a = va_arg(fp->args, Adr*); i = a->type; - if(i >= D_INDIR) { + if(i >= D_INDIR && i < D_CONST2) { if(a->offset) - sprint(str, "%lld(%R)", a->offset, i-D_INDIR); + snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR); else - sprint(str, "(%R)", i-D_INDIR); + snprint(str, sizeof(str), "(%R)", i-D_INDIR); goto brk; } switch(i) { default: if(a->offset) - sprint(str, "$%lld,%R", a->offset, i); + snprint(str, sizeof(str), "$%lld,%R", a->offset, i); else - sprint(str, "%R", i); + snprint(str, sizeof(str), "%R", i); break; case D_NONE: @@ -84,57 +91,57 @@ case D_BRANCH: if(bigP != P && bigP->pcond != P) if(a->sym != S) - sprint(str, "%llux+%s", bigP->pcond->pc, + snprint(str, sizeof(str), "%llux+%s", bigP->pcond->pc, a->sym->name); else - sprint(str, "%llux", bigP->pcond->pc); + snprint(str, sizeof(str), "%llux", bigP->pcond->pc); else - sprint(str, "%lld(PC)", a->offset); + snprint(str, sizeof(str), "%lld(PC)", a->offset); break; case D_EXTERN: - sprint(str, "%s+%lld(SB)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%lld(SB)", a->sym->name, a->offset); break; case D_STATIC: - sprint(str, "%s<%d>+%lld(SB)", a->sym->name, + snprint(str, sizeof(str), "%s<%d>+%lld(SB)", a->sym->name, a->sym->version, a->offset); break; case D_AUTO: - sprint(str, "%s+%lld(SP)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%lld(SP)", a->sym->name, a->offset); break; case D_PARAM: if(a->sym) - sprint(str, "%s+%lld(%s)", a->sym->name, a->offset, paramspace); + snprint(str, sizeof(str), "%s+%lld(%s)", a->sym->name, a->offset, paramspace); else - sprint(str, "%lld(%s)", a->offset, paramspace); + snprint(str, sizeof(str), "%lld(%s)", a->offset, paramspace); break; case D_CONST: - sprint(str, "$%lld", a->offset); + snprint(str, sizeof(str), "$%lld", a->offset); break; case D_FCONST: - sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); + snprint(str, sizeof(str), "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); break; case D_SCONST: - sprint(str, "$\"%S\"", a->scon); + snprint(str, sizeof(str), "$\"%S\"", a->scon); break; case D_ADDR: a->type = a->index; a->index = D_NONE; - sprint(str, "$%D", a); + snprint(str, sizeof(str), "$%D", a); a->index = a->type; a->type = D_ADDR; goto conv; } brk: - if(a->index != D_NONE) { - sprint(s, "(%R*%d)", a->index, a->scale); + if(a->index != D_NONE && !isxyreg(a->type)) { + snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale); strcat(str, s); } conv: @@ -182,23 +189,23 @@ "DH", "BH", - "F0", /* [D_F0] */ - "F1", - "F2", - "F3", - "F4", - "F5", - "F6", - "F7", - - "M0", - "M1", - "M2", - "M3", - "M4", - "M5", - "M6", - "M7", + "Y0", /* [D_Y0] */ + "Y1", + "Y2", + "Y3", + "Y4", + "Y5", + "Y6", + "Y7", + + "Y8", + "Y9", + "Y10", + "Y11", + "Y12", + "Y13", + "Y14", + "Y15", "X0", "X1", @@ -276,9 +283,13 @@ r = va_arg(fp->args, int); if(r >= D_AL && r <= D_NONE) - sprint(str, "%s", regstr[r-D_AL]); + snprint(str, sizeof(str), "%s", regstr[r-D_AL]); + else if(r >= D_Y0 && r <= D_Y15) + snprint(str, sizeof(str), "Y%d", r-D_Y0); + else if(r >= D_M0 && r <= D_M7) + snprint(str, sizeof(str), "Y%d", r-D_M0); else - sprint(str, "gok(%d)", r); + snprint(str, sizeof(str), "gok(%d)", r); return fmtstrcpy(fp, str); } @@ -343,7 +354,7 @@ print("%s: %s\n", tn, buf); nerrors++; - if(nerrors > 20) { + if(nerrors > 20 && !debug['A']) { print("too many errors\n"); errorexit(); } diff -Nru /n/sources/plan9/sys/src/cmd/6l/mkfile /sys/src/cmd/6l/mkfile --- /n/sources/plan9/sys/src/cmd/6l/mkfile Tue Mar 26 23:18:22 2013 +++ /sys/src/cmd/6l/mkfile Mon Dec 14 00:00:00 2015 @@ -15,7 +15,7 @@ HFILES=\ l.h\ ../6c/6.out.h\ - ../8l/elf.h\ + ../ld/elf.h\ BIN=/$objtype/bin CFLAGS=$CFLAGS -. -I. @@ -31,5 +31,5 @@ enam.$O: ../6c/enam.c $CC $CFLAGS ../6c/enam.c -elf.$O: ../8l/elf.c - $CC $CFLAGS ../8l/elf.c +elf.$O: ../ld/elf.c + $CC $CFLAGS ../ld/elf.c diff -Nru /n/sources/plan9/sys/src/cmd/6l/obj.c /sys/src/cmd/6l/obj.c --- /n/sources/plan9/sys/src/cmd/6l/obj.c Tue Mar 26 23:16:29 2013 +++ /sys/src/cmd/6l/obj.c Mon Dec 14 00:00:00 2015 @@ -127,7 +127,7 @@ break; } ARGEND USED(argc); - if(*argv == 0) + if(*argv == nil) usage(); if(!debug['9'] && !debug['U'] && !debug['B']) debug[DEFAULT] = 1; @@ -223,9 +223,8 @@ ycover[Yax*Ymax + Yrb] = 1; ycover[Ycx*Ymax + Yrb] = 1; ycover[Yrx*Ymax + Yrb] = 1; - ycover[Yrl*Ymax + Yrb] = 1; - - ycover[Ycl*Ymax + Ycx] = 1; + ycover[Yrl*Ymax + Yrb] = 1; // 8l disables this + ycover[Ycl*Ymax + Ycx] = 1; // 8l disables this ycover[Yax*Ymax + Yrx] = 1; ycover[Ycx*Ymax + Yrx] = 1; @@ -242,7 +241,7 @@ ycover[Ycx*Ymax + Ymb] = 1; ycover[Yrx*Ymax + Ymb] = 1; ycover[Yrb*Ymax + Ymb] = 1; - ycover[Yrl*Ymax + Ymb] = 1; + ycover[Yrl*Ymax + Ymb] = 1; // 8l disables this ycover[Ym*Ymax + Ymb] = 1; ycover[Yax*Ymax + Yml] = 1; @@ -264,6 +263,10 @@ ycover[Yrl*Ymax + Yxm] = 1; ycover[Ym*Ymax + Yxm] = 1; ycover[Yxr*Ymax + Yxm] = 1; + ycover[Yxr*Ymax + Yxyr] = 1; + + ycover[Yyr*Ymax + Yxm] = 1; + ycover[Yyr*Ymax + Yxyr] = 1; for(i=0; i= D_R8) regrex[i] = Rxr | Rxx | Rxb; } +/* if(i >= D_F0 && i <= D_F0+7) reg[i] = (i-D_F0) & 7; +*/ if(i >= D_M0 && i <= D_M0+7) reg[i] = (i-D_M0) & 7; if(i >= D_X0 && i <= D_X0+15) { @@ -290,6 +295,11 @@ if(i >= D_X0+8) regrex[i] = Rxr | Rxx | Rxb; } + if(i >= D_Y0 && i <= D_Y0+15) { + reg[i] = (i-D_Y0) & 7; + if(i >= D_Y0+8) + regrex[i] = Rxr | Rxx | Rxb; + } if(i >= D_CR+8 && i <= D_CR+15) regrex[i] = Rxr; } @@ -535,8 +545,7 @@ l |= (e[3] & 0xff) << 16; l |= (e[4] & 0xff) << 24; seek(f, l, 0); - /* need readn to read the dumps (at least) */ - l = readn(f, &arhdr, SAR_HDR); + l = read(f, &arhdr, SAR_HDR); if(l != SAR_HDR) goto bad; if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) @@ -579,10 +588,6 @@ } a->offset = 0; if(t & T_OFFSET) { - /* - * Hack until Charles fixes the compiler. - a->offset = (long)(p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24)); - */ l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); a->offset = l; c += 4; diff -Nru /n/sources/plan9/sys/src/cmd/6l/optab.c /sys/src/cmd/6l/optab.c --- /n/sources/plan9/sys/src/cmd/6l/optab.c Thu Jan 31 20:14:09 2013 +++ /sys/src/cmd/6l/optab.c Mon Dec 14 00:00:00 2015 @@ -15,10 +15,10 @@ Ynone, Ynone, Zpseudo,1, Ynone, Yml, Zpseudo,1, Ynone, Yrf, Zpseudo,1, - Ynone, Yxr, Zpseudo,1, + Ynone, Yxyr, Zpseudo,1, Yml, Ynone, Zpseudo,1, Yrf, Ynone, Zpseudo,1, - Yxr, Ynone, Zpseudo,1, + Yxyr, Ynone, Zpseudo,1, 0 }; uchar yxorb[] = @@ -59,6 +59,7 @@ }; uchar yincl[] = { + /* 32-bit one-byte version is rex prefix (48) in 64-bit mode */ Ynone, Yml, Zo_m, 2, 0 }; @@ -178,6 +179,12 @@ Yiauto, Yrl, Zaut_r, 2, // built-in LEAQ 0 }; +uchar ymovqq[] = +{ + Yxm, Yyr, Zm_r_xm, 2, // MOVQQx ymm load + Yyr, Ym, Zr_m_xm_nr, 2, // MOVQQx ymm store + 0 +}; uchar ym_rl[] = { Ym, Yrl, Zm_r, 1, @@ -198,6 +205,16 @@ Yml, Yrl, Zm_r, 1, 0 }; +uchar ycrc[] = +{ + Yml, Yrl, Zm_r_xm, 3, + 0 +}; +uchar ycrcb[] = +{ + Ymb, Yrb, Zm_r_xm, 3, + 0 +}; uchar yrl_ml[] = { Yrl, Yml, Zr_m, 1, @@ -268,6 +285,11 @@ Ynone, Ym, Zo_m, 2, 0 }; +uchar ybswap[] = +{ + Ynone, Yrl, Z_rp, 2, + 0, +}; uchar yscond[] = { Ynone, Ymb, Zo_m, 2, @@ -370,7 +392,7 @@ uchar ymm[] = { Ymm, Ymr, Zm_r_xm, 1, - Yxm, Yxr, Zm_r_xm, 2, + Yxm, Yxyr, Zm_r_xm, 2, 0 }; uchar yxm[] = @@ -471,8 +493,13 @@ }; uchar ymrxr[] = { + Yxm, Yxyr, Zm_r_xm, 2, + 0 +}; +uchar ymrxrmv[] = +{ Ymr, Yxr, Zm_r, 1, - Yxm, Yxr, Zm_r_xm, 1, + Yxm, Yxyr, Zm_r_xm, 1, 0 }; uchar ymshuf[] = @@ -482,7 +509,12 @@ }; uchar yxshuf[] = { - Yxm, Yxr, Zibm_r, 1, + Yxm, Yxyr, Zibm_r, 1, + 0 +}; +uchar yxshuf2[] = +{ + Yxm, Yxyr, Zm_r_i_xm, 2, 0 }; uchar yextrw[] = @@ -492,15 +524,19 @@ }; uchar ypsdq[] = { - Yi8, Yxr, Zibo_m, 2, + Yi8, Yxyr, Zibo_m, 2, 0 }; uchar ymskb[] = { - Yxr, Yrl, Zm_r_xm, 2, + Yxyr, Yrl, Zm_r_xm, 2, Ymr, Yrl, Zm_r_xm, 1, 0 }; +uchar yaes[] = { + Yi8, Yxyr, Zr_m_i_xm, 3, + 0 +}; Optab optab[] = /* as, ytab, andproto, opcode */ @@ -540,6 +576,8 @@ { ABSRL, yml_rl, Pm, 0xbd }, { ABSRQ, yml_rl, Pw, 0x0f,0xbd }, { ABSRW, yml_rl, Pq, 0xbd }, + { ABSWAPL, ybswap, Px, 0x0f,0xc8 }, + { ABSWAPQ, ybswap, Pw, 0x0f,0xc8 }, { ABTCL, ybtl, Pm, 0xba,(07),0xbb }, { ABTCQ, ybtl, Pw, 0x0f,0xba,(07),0x0f,0xbb }, { ABTCW, ybtl, Pq, 0xba,(07),0xbb }, @@ -735,7 +773,7 @@ { ALOOPNE, yloop, Px, 0xe0 }, { ALSLL, yml_rl, Pm, 0x03 }, { ALSLW, yml_rl, Pq, 0x03 }, - { AMASKMOVOU, yxr, Pe, 0xf7 }, + { AMASKMOVDQU, yxr, Pe, 0xf7 }, { AMASKMOVQ, ymr, Pm, 0xf7 }, { AMAXPD, yxm, Pe, 0x5f }, { AMAXPS, yxm, Pm, 0x5f }, @@ -745,8 +783,8 @@ { AMINPS, yxm, Pm, 0x5d }, { AMINSD, yxm, Pf2, 0x5d }, { AMINSS, yxm, Pf3, 0x5d }, - { AMOVAPD, yxmov, Pe, 0x28,0x29 }, - { AMOVAPS, yxmov, Pm, 0x28,0x29 }, + { AMOVAPD, yxmov, Pe|P2, 0x28,0x29 }, + { AMOVAPS, yxmov, Pm|P2, 0x28,0x29 }, { AMOVB, ymovb, Pb, 0x88,0x8a,0xb0,0xc6,(00) }, { AMOVBLSX, ymb_rl, Pm, 0xbe }, { AMOVBLZX, ymb_rl, Pm, 0xb6 }, @@ -755,32 +793,36 @@ { AMOVBWSX, ymb_rl, Pq, 0xbe }, { AMOVBWZX, ymb_rl, Pq, 0xb6 }, { AMOVO, yxmov, Pe, 0x6f,0x7f }, - { AMOVOU, yxmov, Pf3, 0x6f,0x7f }, + { AMOVDQA, yxmov, Pe|P2, 0x6f,0x7f }, + { AMOVDQU, yxmov, Pf3|P2, 0x6f,0x7f }, { AMOVHLPS, yxr, Pm, 0x12 }, - { AMOVHPD, yxmov, Pe, 0x16,0x17 }, - { AMOVHPS, yxmov, Pm, 0x16,0x17 }, + { AMOVHPD, yxmov, Pe|P2, 0x16,0x17 }, + { AMOVHPS, yxmov, Pm|P2, 0x16,0x17 }, { AMOVL, ymovl, Px, 0x89,0x8b,0x31,0xb8,0xc7,(00),0x6e,0x7e,Pe,0x6e,Pe,0x7e }, { AMOVLHPS, yxr, Pm, 0x16 }, - { AMOVLPD, yxmov, Pe, 0x12,0x13 }, - { AMOVLPS, yxmov, Pm, 0x12,0x13 }, + { AMOVLPD, yxmov, Pe|P2, 0x12,0x13 }, + { AMOVLPS, yxmov, Pm|P2, 0x12,0x13 }, { AMOVLQSX, yml_rl, Pw, 0x63 }, { AMOVLQZX, yml_rl, Px, 0x8b }, { AMOVMSKPD, yxrrl, Pq, 0x50 }, { AMOVMSKPS, yxrrl, Pm, 0x50 }, - { AMOVNTO, yxr_ml, Pe, 0xe7 }, + { AMOVNTDQ, yxr_ml, Pe, 0xe7 }, { AMOVNTPD, yxr_ml, Pe, 0x2b }, { AMOVNTPS, yxr_ml, Pm, 0x2b }, { AMOVNTQ, ymr_ml, Pm, 0xe7 }, - { AMOVQ, ymovq, Pw, 0x89,0x8b,0x31,0xc7,(00),0xb8,0xc7,(00),0x6f,0x7f,0x6e,0x7e,Pf2,0xd6,Pe,0xd6,Pe,0x6e,Pe,0x7e }, - { AMOVQOZX, ymrxr, Pf3, 0xd6,0x7e }, + { AMOVQ, ymovq, Pw|P2, 0x89,0x8b,0x31,0xc7,(00),0xb8,0xc7,(00),0x6f,0x7f,0x6e,0x7e,Pf2,0xd6,Pe,0xd6,Pe,0x6e,Pe,0x7e }, + { AMOVQL, yrl_ml, Px, 0x89 }, + { AMOVQQA, ymovqq, P2, Pe,0x6f,Pe,0x7f }, + { AMOVQQU, ymovqq, P2, Pf3,0x6f,Pf3,0x7f }, + { AMOVQOZX, ymrxrmv, Pf3, 0xd6,0x7e }, { AMOVSB, ynone, Pb, 0xa4 }, - { AMOVSD, yxmov, Pf2, 0x10,0x11 }, + { AMOVSD, yxmov, Pf2|P2, 0x10,0x11 }, { AMOVSL, ynone, Px, 0xa5 }, { AMOVSQ, ynone, Pw, 0xa5 }, - { AMOVSS, yxmov, Pf3, 0x10,0x11 }, + { AMOVSS, yxmov, Pf3|P2, 0x10,0x11 }, { AMOVSW, ynone, Pe, 0xa5 }, - { AMOVUPD, yxmov, Pe, 0x10,0x11 }, - { AMOVUPS, yxmov, Pm, 0x10,0x11 }, + { AMOVUPD, yxmov, Pe|P2, 0x10,0x11 }, + { AMOVUPS, yxmov, Pm|P2, 0x10,0x11 }, { AMOVW, ymovw, Pe, 0x89,0x8b,0x31,0xb8,0xc7,(00) }, { AMOVWLSX, yml_rl, Pm, 0xbf }, { AMOVWLZX, yml_rl, Pm, 0xb7 }, @@ -816,8 +858,12 @@ { AOUTSL, ynone, Px, 0x6f }, { AOUTSW, ynone, Pe, 0x6f }, { AOUTW, yin, Pe, 0xe7,0xef }, + { APABSB, ymrxr, Pe, Pm38,0x1c }, + { APABSL, ymrxr, Pe, Pm38,0x1e }, + { APABSW, ymrxr, Pe, Pm38,0x1d }, { APACKSSLW, ymm, Py, 0x6b,Pe,0x6b }, { APACKSSWB, ymm, Py, 0x63,Pe,0x63 }, + { APACKUSDW, ymrxr, Pe, Pm38,0x2b }, { APACKUSWB, ymm, Py, 0x67,Pe,0x67 }, { APADDB, ymm, Py, 0xfc,Pe,0xfc }, { APADDL, ymm, Py, 0xfe,Pe,0xfe }, @@ -833,6 +879,8 @@ { APAVGW, ymm, Py, 0xe3,Pe,0xe3 }, { APCMPEQB, ymm, Py, 0x74,Pe,0x74 }, { APCMPEQL, ymm, Py, 0x76,Pe,0x76 }, + { APCMPEQQ, ymrxr, Pe, Pm38,0x29 }, + { APCMPGTQ, ymrxr, Pe, Pm38,0x37 }, { APCMPEQW, ymm, Py, 0x75,Pe,0x75 }, { APCMPGTB, ymm, Py, 0x64,Pe,0x64 }, { APCMPGTL, ymm, Py, 0x66,Pe,0x66 }, @@ -858,13 +906,44 @@ { APFRSQRT, ymfp, Px, 0x97 }, { APFSUB, ymfp, Px, 0x9a }, { APFSUBR, ymfp, Px, 0xaa }, + { APHADDL, ymrxr, Pe, Pm38,0x02 }, + { APHADDSW, ymrxr, Pe, Pm38,0x03 }, + { APHADDW, ymrxr, Pe, Pm38,0x01 }, + { APHMINPOSUW, ymrxr, Pe, Pm38,0x41 }, + { APHSUBL, ymrxr, Pe, Pm38,0x06 }, + { APHSUBSW, ymrxr, Pe, Pm38,0x07 }, + { APHSUBW, ymrxr, Pe, Pm38,0x05 }, { APINSRW, yextrw, Pq, 0xc4 }, + { APMADDUBSW, ymrxr, Pe, Pm38,0x04 }, { APMADDWL, ymm, Py, 0xf5,Pe,0xf5 }, + { APMAXSB, ymrxr, Pe, Pm38,0x3c }, + { APMAXSL, ymrxr, Pe, Pm38,0x3d }, { APMAXSW, yxm, Pe, 0xee }, { APMAXUB, yxm, Pe, 0xde }, + { APMAXUL, ymrxr, Pe, Pm38,0x3f }, + { APMAXUW, ymrxr, Pe, Pm38,0x3e }, + { APMINSB, ymrxr, Pe, Pm38,0x38 }, + { APMINSL, ymrxr, Pe, Pm38,0x39 }, + { APMINUL, ymrxr, Pe, Pm38,0x3b }, + { APMINUW, ymrxr, Pe, Pm38,0x3a }, { APMINSW, yxm, Pe, 0xea }, { APMINUB, yxm, Pe, 0xda }, - { APMOVMSKB, ymskb, Px, Pe,0xd7,0xd7 }, + { APMOVMSKB, ymskb, Px|P2, Pe,0xd7,0xd7 }, + { APMOVSXBL, ymrxr, Pe, Pm38,0x21 }, + { APMOVSXBQ, ymrxr, Pe, Pm38,0x22 }, + { APMOVSXBW, ymrxr, Pe, Pm38,0x20 }, + { APMOVSXLQ, ymrxr, Pe, Pm38,0x25 }, + { APMOVSXWL, ymrxr, Pe, Pm38,0x23 }, + { APMOVSXWQ, ymrxr, Pe, Pm38,0x24 }, + { APMOVZXBL, ymrxr, Pe, Pm38,0x31 }, + { APMOVZXBQ, ymrxr, Pe, Pm38,0x32 }, + { APMOVZXBW, ymrxr, Pe, Pm38,0x30 }, + { APMOVZXLQ, ymrxr, Pe, Pm38,0x35 }, + { APMOVZXWL, ymrxr, Pe, Pm38,0x33 }, + { APMOVZXWQ, ymrxr, Pe, Pm38,0x34 }, + { APMULLL, ymrxr, Pe, Pm38,0x40 }, + { APMULLQ, ymrxr, Pe, Pm38,0x28 }, + { APMULHRSW, ymrxr, Pe, Pm38,0x0b }, { APMULHRW, ymfp, Px, 0xb7 }, { APMULHUW, ymm, Py, 0xe4,Pe,0xe4 }, { APMULHW, ymm, Py, 0xe5,Pe,0xe5 }, @@ -880,17 +959,21 @@ { APOPW, ypopl, Pe, 0x58,0x8f,(00) }, { APOR, ymm, Py, 0xeb,Pe,0xeb }, { APSADBW, yxm, Pq, 0xf6 }, + { APSHUFB, ymrxr, Pe, Pm38,0x00 }, { APSHUFHW, yxshuf, Pf3, 0x70 }, { APSHUFL, yxshuf, Pq, 0x70 }, { APSHUFLW, yxshuf, Pf2, 0x70 }, { APSHUFW, ymshuf, Pm, 0x70 }, - { APSLLO, ypsdq, Pq, 0x73,(07) }, + { APSIGNB, ymrxr, Pe, Pm38,0x08 }, + { APSIGNL, ymrxr, Pe, Pm38,0x0a }, + { APSIGNW, ymrxr, Pe, Pm38,0x09 }, + { APSLLDQ, ypsdq, Pq, 0x73,(07) }, { APSLLL, yps, Py, 0xf2, 0x72,(06), Pe,0xf2, Pe,0x72,(06) }, { APSLLQ, yps, Py, 0xf3, 0x73,(06), Pe,0xf3, Pe,0x7e,(06) }, { APSLLW, yps, Py, 0xf1, 0x71,(06), Pe,0xf1, Pe,0x71,(06) }, { APSRAL, yps, Py, 0xe2, 0x72,(04), Pe,0xe2, Pe,0x72,(04) }, { APSRAW, yps, Py, 0xe1, 0x71,(04), Pe,0xe1, Pe,0x71,(04) }, - { APSRLO, ypsdq, Pq, 0x73,(03) }, + { APSRLDQ, ypsdq, Pq, 0x73,(03) }, { APSRLL, yps, Py, 0xd2, 0x72,(02), Pe,0xd2, Pe,0x72,(02) }, { APSRLQ, yps, Py, 0xd3, 0x73,(02), Pe,0xd3, Pe,0x73,(02) }, { APSRLW, yps, Py, 0xd1, 0x71,(02), Pe,0xe1, Pe,0x71,(02) }, @@ -903,6 +986,7 @@ { APSUBUSW, yxm, Pe, 0xd9 }, { APSUBW, yxm, Pe, 0xf9 }, { APSWAPL, ymfp, Px, 0xbb }, + { APTEST, ymrxr, Pe, Pm38,0x17 }, { APUNPCKHBW, ymm, Py, 0x68,Pe,0x68 }, { APUNPCKHLQ, ymm, Py, 0x6a,Pe,0x6a }, { APUNPCKHQDQ, yxm, Pe, 0x6d }, @@ -925,8 +1009,8 @@ { ARCLL, yshl, Px, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) }, { ARCLQ, yshl, Pw, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) }, { ARCLW, yshl, Pe, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) }, - { ARCPPS, yxm, Pm, 0x53 }, - { ARCPSS, yxm, Pf3, 0x53 }, + { ARCPPS, yxm, Pm|P2, 0x53 }, + { ARCPSS, yxm, Pf3|P2, 0x53 }, { ARCRB, yshb, Pb, 0xd0,(03),0xc0,(03),0xd2,(03) }, { ARCRL, yshl, Px, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) }, { ARCRQ, yshl, Pw, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) }, @@ -945,8 +1029,8 @@ { ARORL, yshl, Px, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) }, { ARORQ, yshl, Pw, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) }, { ARORW, yshl, Pe, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) }, - { ARSQRTPS, yxm, Pm, 0x52 }, - { ARSQRTSS, yxm, Pf3, 0x52 }, + { ARSQRTPS, yxm, Pm|P2, 0x52 }, + { ARSQRTSS, yxm, Pf3|P2, 0x52 }, { ASAHF, ynone, Px, 0x86,0xe0,0x50,0x9d }, /* XCHGB AH,AL; PUSH AX; POPFL */ { ASALB, yshb, Pb, 0xd0,(04),0xc0,(04),0xd2,(04) }, { ASALL, yshl, Px, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) }, @@ -990,10 +1074,10 @@ { ASHRW, yshl, Pe, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) }, { ASHUFPD, yxshuf, Pq, 0xc6 }, { ASHUFPS, yxshuf, Pm, 0xc6 }, - { ASQRTPD, yxm, Pe, 0x51 }, - { ASQRTPS, yxm, Pm, 0x51 }, - { ASQRTSD, yxm, Pf2, 0x51 }, - { ASQRTSS, yxm, Pf3, 0x51 }, + { ASQRTPD, yxm, Pe|P2, 0x51 }, + { ASQRTPS, yxm, Pm|P2, 0x51 }, + { ASQRTSD, yxm, Pf2|P2, 0x51 }, + { ASQRTSS, yxm, Pf3|P2, 0x51 }, { ASTC, ynone, Px, 0xf9 }, { ASTD, ynone, Px, 0xfd }, { ASTI, ynone, Px, 0xfb }, @@ -1150,6 +1234,7 @@ { ACMPXCHGL, yrl_ml, Px, 0x0f,0xb1 }, { ACMPXCHGW, yrl_ml, Pe, 0x0f,0xb1 }, { ACMPXCHGQ, yrl_ml, Pw, 0x0f,0xb1 }, + { ACMPXCHG16B, yscond, Pw, 0x0f,0xc7,(01) }, { ACMPXCHG8B, yscond, Pm, 0xc7,(01) }, { AINVD, ynone, Pm, 0x08 }, { AINVLPG, ymbs, Pm, 0x01,(07) }, @@ -1171,15 +1256,31 @@ { AXADDQ, yrl_ml, Pw, 0x0f,0xc1 }, { AXADDW, yrl_ml, Pe, 0x0f,0xc1 }, + { APALIGNR, yxshuf2, Pe, Pm3a,0x0f }, + + { AXSAVE, ysvrs, Pm, 0xae,(04),0xae,(04) }, + { AXSAVEOPT, ysvrs, Pm, 0xae,(06),0xae,(06) }, + { AXRSTOR, ysvrs, Pm, 0xae,(05),0xae,(05) }, + + { ACRC32L, ycrc, Px, Pf2,0x38,0xf1 }, + { ACRC32W, ycrc, Pe, Pf2,0x38,0xf1 }, + { ACRC32B, ycrcb, Pb, Pf2,0x38,0xf0 }, + { ACRC32Q, ycrc, Pw, Pf2,0x38,0xf1 }, + { APAUSE, ynone, Px, 0xf3,0x90 }, + + { AAESIMC, yxm, Pe, Pm38, 0xdb }, + { AAESENC, yxm, Pe, Pm38, 0xdc }, + { AAESENCLAST, yxm, Pe, Pm38, 0xdd }, + { AAESDEC, yxm, Pe, Pm38, 0xde }, + { AAESDECLAST, yxm, Pe, Pm38, 0xdf }, + { AAESKEYGENASSIST, yaes, Pe, Pm3a, 0xdf }, + { APCLMULQDQ, yaes, Pe, Pm3a, 0x44 }, + + { ABLENDPS, yaes, Pe, Pm3a, 0xdc }, + { ABLENDPD, yaes, Pe, Pm3a, 0x0d }, + { AEND }, 0 }; Optab* opindex[ALAST+1]; - -/* -AMOVD 0f 6e/r mmx,reg/mem32[mem64-rex?] -AMOVD 0f 7e/r reg/mem32[64],mmx STORE -AMOVQ 0f 6f/r mmx1,mmx2/mem64 -AMOVQ 0f 7f/r mmx1/mem64,mmx2 -*/ diff -Nru /n/sources/plan9/sys/src/cmd/6l/pass.c /sys/src/cmd/6l/pass.c --- /n/sources/plan9/sys/src/cmd/6l/pass.c Mon Dec 8 12:52:09 2008 +++ /sys/src/cmd/6l/pass.c Mon Dec 14 00:00:00 2015 @@ -99,8 +99,10 @@ s->value = bsssize + datsize; bsssize += t; } + xdefine("bdata", SDATA, 0L); xdefine("edata", SBSS, datsize); xdefine("end", SBSS, bsssize + datsize); + /* etext is defined in span.c */ } Prog* @@ -157,7 +159,7 @@ if(q == lastp) break; a = q->as; - if(a == ANOP) { + if(a == ANOP || a == ATEXT) { i--; continue; } @@ -229,11 +231,19 @@ if(a == AJMP || a == ARET || a == AIRETL || a == AIRETQ || a == AIRETW || a == ARETFL || a == ARETFQ || a == ARETFW) return; + if(a == ATEXT) { + xfol(p->link); + q = p->pcond; + if(q == P || q->mark) + return; + p = q; + goto loop; + } if(p->pcond != P) if(a != ACALL) { q = brchain(p->link); if(q != P && q->mark) - if(a != ALOOP) { + if(a != ALOOP && a != ATEXT) { p->as = relinv(a); p->link = p->pcond; p->pcond = q; @@ -326,7 +336,8 @@ Bprint(&bso, "%s calls %s\n", TNAME, s->name); switch(s->type) { default: - diag("undefined: %s in %s", s->name, TNAME); + /* diag prints TNAME first */ + diag("undefined: %s", s->name); s->type = STEXT; s->value = vexit; break; /* or fall through to set offset? */ @@ -656,7 +667,8 @@ if(s->value != 0) diag("value != 0 on SXREF"); undefsym(s); - Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, s->value); + if(debug['X']) + Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, s->value); if(debug['S']) s->sig = 0; } @@ -701,14 +713,14 @@ n = 0; for(i = 0; i < NHASH; i++) for(s = hash[i]; s != S; s = s->link) - if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT)) + if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport)) n++; esyms = malloc(n*sizeof(Sym*)); ne = n; n = 0; for(i = 0; i < NHASH; i++) for(s = hash[i]; s != S; s = s->link) - if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT)) + if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport)) esyms[n++] = s; for(i = 0; i < ne-1; i++) for(j = i+1; j < ne; j++) diff -Nru /n/sources/plan9/sys/src/cmd/6l/span.c /sys/src/cmd/6l/span.c --- /n/sources/plan9/sys/src/cmd/6l/span.c Thu Mar 28 17:51:09 2013 +++ /sys/src/cmd/6l/span.c Mon Dec 14 00:00:00 2015 @@ -1,6 +1,7 @@ #include "l.h" static int rexflag; +static int vexbytes; static int asmode; void @@ -321,12 +322,30 @@ } int +prefixof(Adr *a) +{ + switch(a->type) { + case D_INDIR+D_CS: + return 0x2e; + case D_INDIR+D_DS: + return 0x3e; + case D_INDIR+D_ES: + return 0x26; + case D_INDIR+D_FS: + return 0x64; + case D_INDIR+D_GS: + return 0x65; + } + return 0; +} + +int oclass(Adr *a) { vlong v; long l; - if(a->type >= D_INDIR || a->index != D_NONE) { + if(a->type < D_CONST2 && (a->type >= D_INDIR || !isxyreg(a->type) && a->index != D_NONE)) { if(a->index != D_NONE && a->scale == 0) { if(a->type == D_ADDR) { switch(a->index) { @@ -401,6 +420,7 @@ case D_DI: return Yrl; +/* case D_F0+0: return Yf0; @@ -412,6 +432,7 @@ case D_F0+6: case D_F0+7: return Yrf; +*/ case D_M0+0: case D_M0+1: @@ -441,6 +462,24 @@ case D_X0+15: return Yxr; + case D_Y0+0: + case D_Y0+1: + case D_Y0+2: + case D_Y0+3: + case D_Y0+4: + case D_Y0+5: + case D_Y0+6: + case D_Y0+7: + case D_Y0+8: + case D_Y0+9: + case D_Y0+10: + case D_Y0+11: + case D_Y0+12: + case D_Y0+13: + case D_Y0+14: + case D_Y0+15: + return Yyr; + case D_NONE: return Ynone; @@ -674,11 +713,14 @@ int t; Adr aa; + if(r == -1) + diag("asmandsz: immedate instead of register"); + rex &= (0x40 | Rxr); v = a->offset; t = a->type; - if(a->index != D_NONE) { - if(t >= D_INDIR) { + if(a->index != D_NONE && !isxyreg(t)) { + if(t >= D_INDIR && t < D_CONST2) { t -= D_INDIR; rexflag |= (regrex[a->index] & Rxx) | (regrex[t] & Rxb) | rex; if(t == D_NONE) { @@ -721,17 +763,26 @@ asmandsz(&aa, r, rex, m64); return; } - if(t >= D_AL && t <= D_X0+15) { + if(t >= D_AL && t <= D_BH) { if(v) goto bad; *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3); rexflag |= (regrex[t] & (0x40 | Rxb)) | rex; return; } - if(t >= D_INDIR) { + if(t >= D_X0 && t <= D_X15 || t >= D_Y0 && t <= D_Y15) { + if(v) + goto bad; + *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3); + if(t >= D_Y0 && t <= D_Y15) + vexbytes |= Vexl; + rexflag |= (regrex[t] & (0x40 | Rxb)) | rex; + return; + } + if(t >= D_INDIR && t < D_CONST2) { t -= D_INDIR; rexflag |= (regrex[t] & Rxb) | rex; - if(t == D_NONE) { + if(t == D_NONE || D_CS <= t && t <= D_GS) { if(asmode != 64){ *andptr++ = (0 << 6) | (5 << 0) | (r << 3); put4(v); @@ -799,6 +850,29 @@ return; } +int +isxyreg(int t) +{ + return t >= D_X0 && t <= D_X15 || t >= D_Y0 && t <= D_Y15; +} + +static void +vexreg(Adr *a) +{ + int t; + + t = a->type; + if(t >= D_Y0 && t <= D_Y15) { + vexbytes |= Vexl; + } else if(t >= D_X0 && t <= D_X15) { + if(vexed) + vexbytes |= Vexr; /* force vex prefix */ + } else + return; + if(a->index != D_NONE) + vexbytes |= a->index << 8; +} + void asmand(Adr *a, Adr *ra) { @@ -806,9 +880,57 @@ } void +asmandg(Adr *a, Adr *r, int o, int rdest, int prefix) +{ + Adr aa, rr; + + if(isxyreg(a->type)) { + if(isxyreg(a->index) && r->type == D_CONST) { + /* + * convert sse instructions with immediate like + * AESKEYGENASSIST $32, X1, X2 from + * a=X1(X2*0); r=$32 to a=X1, r=X2. the + * caller adds the immediate byte. vex is not required + */ + rr.offset = 0; + rr.sym = a->sym; + rr.type = a->index; + rr.index = D_NONE; + rr.scale = 0; + r = &rr; + + aa = *a; + aa.index = D_NONE; + a = &aa; + } + } + vexreg(a); + if(isxyreg(a->type)) { + if(a->index != D_NONE) { + aa = *a; + aa.index = D_NONE; + a = &aa; + } + } + if(r == nil) { + asmandsz(a, o, 0, 0); + return; + } + vexreg(r); + if(rdest && (prefix&P2) == 0 && vexbytes != 0 && (vexbytes>>8) == 0) { + /* copy destination register as second source register */ + if(isxyreg(r->type)) { + vexbytes |= r->type << 8; + rexflag |= regrex[r->type] & Rxx; + } + } + asmand(a, r); +} + +void asmando(Adr *a, int o) { - asmandsz(a, o, 0, 0); + asmandg(a, nil, o, 0, 0); } static void @@ -996,6 +1118,13 @@ mediaop(Optab *o, int op, int osize, int z) { switch(op){ + case Pm38: + case Pm3a: + *andptr++ = Pm; /* 0f */ + *andptr++ = op; /* 38 | 3a */ + op = o->op[++z]; + break; + case Pm: case Pe: case Pf2: @@ -1005,6 +1134,10 @@ *andptr++ = op; *andptr++ = Pm; op = o->op[++z]; + if(op == Pm38 || op == Pm3a) { + *andptr++ = op; + op = o->op[++z]; + } break; } default: @@ -1023,8 +1156,16 @@ Prog *q, pp; uchar *t; Movtab *mo; - int z, op, ft, tt, xo, l; + int z, op, ft, tt, xo, l, pre; vlong v; + Adr vmi; + + pre = prefixof(&p->from); + if(pre) + *andptr++ = pre; + pre = prefixof(&p->to); + if(pre) + *andptr++ = pre; o = opindex[p->as]; if(o == nil) { @@ -1038,7 +1179,7 @@ diag("asmins: noproto %P", p); return; } - xo = o->op[0] == 0x0f; + xo = o->op[0] == Pm; for(z=0; *t; z+=t[3]+xo,t+=4) if(ycover[ft+t[0]]) if(ycover[tt+t[1]]) @@ -1046,7 +1187,7 @@ goto domov; found: - switch(o->prefix) { + switch(o->prefix & 0xFF) { case Pq: /* 16 bit escape and opcode escape */ *andptr++ = Pe; *andptr++ = Pm; @@ -1054,7 +1195,7 @@ case Pf2: /* xmm opcode escape */ case Pf3: - *andptr++ = o->prefix; + *andptr++ = o->prefix & 0xFF; *andptr++ = Pm; break; @@ -1111,36 +1252,36 @@ /* fall through */ case Zm_r: *andptr++ = op; - asmand(&p->from, &p->to); + asmandg(&p->from, &p->to, 0, 1, o->prefix); break; case Zm_r_xm: mediaop(o, op, t[3], z); - asmand(&p->from, &p->to); + asmandg(&p->from, &p->to, 0, 1, o->prefix); break; case Zm_r_xm_nr: rexflag = 0; mediaop(o, op, t[3], z); - asmand(&p->from, &p->to); + asmandg(&p->from, &p->to, 0, 1, o->prefix); break; case Zm_r_i_xm: mediaop(o, op, t[3], z); - asmand(&p->from, &p->to); + asmandg(&p->from, &p->to, 0, 1, o->prefix); *andptr++ = p->to.offset; break; case Zm_r_3d: *andptr++ = 0x0f; *andptr++ = 0x0f; - asmand(&p->from, &p->to); + asmandg(&p->from, &p->to, 0, 1, o->prefix); *andptr++ = op; break; case Zibm_r: *andptr++ = op; - asmand(&p->from, &p->to); + asmandg(&p->from, &p->to, 0, 1, o->prefix); *andptr++ = p->to.offset; break; @@ -1167,18 +1308,18 @@ case Zr_m_xm: mediaop(o, op, t[3], z); - asmand(&p->to, &p->from); + asmandg(&p->to, &p->from, 0, 0, o->prefix); break; case Zr_m_xm_nr: rexflag = 0; mediaop(o, op, t[3], z); - asmand(&p->to, &p->from); + asmandg(&p->to, &p->from, 0, 0, o->prefix); break; case Zr_m_i_xm: mediaop(o, op, t[3], z); - asmand(&p->to, &p->from); + asmandg(&p->to, &p->from, 0, 0, o->prefix); *andptr++ = p->from.offset; break; @@ -1206,8 +1347,13 @@ break; case Zibo_m_xm: + vmi = p->to; + if(p->to.index != D_NONE) { /* VMI has "non-destructive dest" with dest in Vex.vvvv */ + vmi.type = p->to.index; + vmi.index = p->to.type; + } z = mediaop(o, op, t[3], z); - asmando(&p->to, o->op[z+1]); + asmando(&vmi, o->op[z+1]); *andptr++ = v; break; @@ -1472,6 +1618,10 @@ return; } } + if(0) { + int ft = oclass(&p->from), tt = oclass(&p->to); extern char* yclname[]; + fprint(2, "ft=%d [%s] tt=%d [%s]\n", ft, yclname[ft], tt, yclname[tt]); + } diag("doasm: notfound from=%ux to=%ux %P", p->from.type, p->to.type, p); return; @@ -1566,37 +1716,123 @@ break; } break; + + case 7: /* imul rm,r */ + *andptr++ = t[4]; + *andptr++ = t[5]; + asmand(&p->from, &p->to); + break; } } void asmins(Prog *p) { - int n, np, c; + int n, np, o, c, t, v1, v2, vexlen; + vexbytes = 0; rexflag = 0; andptr = and; asmode = p->mode; doasm(p); - if(rexflag){ - /* - * as befits the whole approach of the architecture, - * the rex prefix must appear before the first opcode byte - * (and thus after any 66/67/f2/f3/26/2e/3e prefix bytes, but - * before the 0f opcode escape!), or it might be ignored. - * note that the handbook often misleadingly shows 66/f2/f3 in `opcode'. - */ - if(p->mode != 64) - diag("asmins: illegal in mode %d: %P", p->mode, p); - n = andptr - and; - for(np = 0; np < n; np++) { - c = and[np]; - if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26) + if(vexbytes == 0) { + if(rexflag) { + if(0) fprint(2, "rexflag=%#ux %P\n", rexflag, p); + /* + * the rex prefix must appear before the first opcode byte + * and thus after any 66/67/f2/f3/26/2e/3e prefix bytes, but + * before the 0f opcode escape. + * note that the handbook often misleadingly shows 66/f2/f3 in `opcode'. + */ + if(p->mode != 64) + diag("asmins: illegal in mode %d: %P", p->mode, p); + n = andptr - and; + for(np = 0; np < n; np++) { + c = and[np]; + if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26) + break; + } + memmove(and+np+1, and+np, n-np); + and[np] = 0x40 | rexflag; + andptr++; + } + return; + } + if(0) if(rexflag||vexbytes)fprint(2, "rexflag=%#ux vexbytes=%#ux %P\n", rexflag, vexbytes, p); + n = andptr - and; +//vex if need vvvv register or W or L. never need R X B (must be 1 in 32-bit) +//note: 4th register encoding in immediate byte + /* media/sse/vex: seg* (66|F3|F2)? 0F (38|3A)? op -> seg* vex2|vex3 op */ + for(np = 0; np < n; np++) { /* seg* */ + c = and[np]; + if(c != 0x2e && c != 0x3e && c != 0x26 && c != 0x64 && c != 0x65) + break; + } + o = np; + if(np+1 < n) { + v1 = 0; + v2 = (vexbytes & Vexl) | Vexp0; + switch(and[np]) { + case 0x66: + v2 |= Vexp66; + np++; + break; + case 0xF3: + v2 |= Vexpf3; + np++; + break; + case 0xF2: + v2 |= Vexpf2; + np++; + break; + } + c = and[np]; + if(c == Vex2 || c == Vex3) + return; /* already vexed */ + if(and[np] != 0x0F) { + diag("internal: inconsistent vex state: %P", p); + return; + } + np++; + if(np < n) { + switch(and[np]) { + case 0x38: + v1 = Vex0f38; + np++; + break; + case 0x3a: + v1 = Vex0f3a; + np++; + break; + default: + if(rexflag & (Rxw|Rxx|Rxb)) + v1 = Vex0f; /* force 3-byte vex */ break; + } + } + t = vexbytes >> 8; + if(t >= D_Y0 && t <= D_Y15) + t -= D_Y0; + else if(t >= D_X0 && t <= D_X15) + t -= D_X0; + v2 |= (~t & 0xF) << 3; + vexlen = 2; + if(v1 != 0) + vexlen = 3; + if(o+vexlen != np) { + memmove(and+o+vexlen, and+np, n-np); + andptr = and+(o+vexlen)+(n-np); + } + if(vexlen == 2) { + and[o] = Vex2; + and[o+1] = v2 | ((~rexflag<<5) & Vexr); + } else { + and[o] = Vex3; + and[o+1] = v1 | ((~rexflag<<5) & (Vexr | Vexx | Vexb)); + if(rexflag & Rxw) + v2 |= Vexw; + and[o+2] = v2; } - memmove(and+np+1, and+np, n-np); - and[np] = 0x40 | rexflag; - andptr++; } } @@ -1752,3 +1988,74 @@ Bprint(&bso, "export table entries = %d\n", exports); } } + +char* yclname[] ={ + [Yxxx] "Yxxx", + [Ynone] "Ynone", + [Yi0] "Yi0", + [Yi1] "Yi1", + [Yi8] "Yi8", + [Ys32] "Ys32", + [Yi32] "Yi32", + [Yi64] "Yi64", + [Yiauto] "Yiauto", + [Yal] "Yal", + [Ycl] "Ycl", + [Yax] "Yax", + [Ycx] "Ycx", + [Yrb] "Yrb", + [Yrl] "Yrl", + [Yrf] "Yrf", + [Yf0] "Yf0", + [Yrx] "Yrx", + [Ymb] "Ymb", + [Yml] "Yml", + [Ym] "Ym", + [Ybr] "Ybr", + [Ycol] "Ycol", + [Ycs] "Ycs", + [Yss] "Yss", + [Yds] "Yds", + [Yes] "Yes", + [Yfs] "Yfs", + [Ygs] "Ygs", + [Ygdtr] "Ygdtr", + [Yidtr] "Yidtr", + [Yldtr] "Yldtr", + [Ymsw] "Ymsw", + [Ytask] "Ytask", + [Ycr0] "Ycr0", + [Ycr1] "Ycr1", + [Ycr2] "Ycr2", + [Ycr3] "Ycr3", + [Ycr4] "Ycr4", + [Ycr5] "Ycr5", + [Ycr6] "Ycr6", + [Ycr7] "Ycr7", + [Ycr8] "Ycr8", + [Ydr0] "Ydr0", + [Ydr1] "Ydr1", + [Ydr2] "Ydr2", + [Ydr3] "Ydr3", + [Ydr4] "Ydr4", + [Ydr5] "Ydr5", + [Ydr6] "Ydr6", + [Ydr7] "Ydr7", + [Ytr0] "Ytr0", + [Ytr1] "Ytr1", + [Ytr2] "Ytr2", + [Ytr3] "Ytr3", + [Ytr4] "Ytr4", + [Ytr5] "Ytr5", + [Ytr6] "Ytr6", + [Ytr7] "Ytr7", + [Yrl32] "Yrl32", + [Yrl64] "Yrl64", + [Ymr] "Ymr", + [Ymm] "Ymm", + [Yxr] "Yxr", + [Yxm] "Yxm", + [Yyr] "Yyr", + [Yxyr] "Yxyr", + [Ymax] "Ymax", +}; diff -Nru /n/sources/plan9/sys/src/cmd/8c/gc.h /sys/src/cmd/8c/gc.h --- /n/sources/plan9/sys/src/cmd/8c/gc.h Mon Mar 4 21:15:20 2013 +++ /sys/src/cmd/8c/gc.h Mon Dec 14 00:00:00 2015 @@ -122,7 +122,7 @@ Node* scope; }; -#define NRGN 600 +#define NRGN 1000 struct Rgn { Reg* enter; diff -Nru /n/sources/plan9/sys/src/cmd/8c/machcap.c /sys/src/cmd/8c/machcap.c --- /n/sources/plan9/sys/src/cmd/8c/machcap.c Wed Nov 16 23:45:56 2011 +++ /sys/src/cmd/8c/machcap.c Mon Dec 14 00:00:00 2015 @@ -18,7 +18,7 @@ if(typev[n->type->etype]) { // if(typev[n->type->etype] && n->right->op == OCONST) { // if(hi64v(n->right) == 0) - return 1; + return !mixedasop(n->type, n->right->type); } break; @@ -58,10 +58,13 @@ case OASADD: case OASSUB: + return !mixedasop(n->type, n->right->type); + case OASAND: case OASOR: case OASXOR: return 1; + case OASASHL: case OASASHR: diff -Nru /n/sources/plan9/sys/src/cmd/8c/sgen.c /sys/src/cmd/8c/sgen.c --- /n/sources/plan9/sys/src/cmd/8c/sgen.c Wed Nov 16 23:49:58 2011 +++ /sys/src/cmd/8c/sgen.c Mon Dec 14 00:00:00 2015 @@ -46,6 +46,28 @@ } } +static int +indexing(Node *n) +{ + for(; n != nil; n = n->left) + switch(n->op){ + case OSIGN: + case OSIZE: + case OCONST: + case OSTRING: + case OLSTRING: + case ONAME: + case OREGPAIR: + case OREGISTER: + case OINDREG: + return 0; + case OINDEX: + return 1; + } + return 0; +} + + /* * calculate addressability as follows * NAME ==> 10/11 name+value(SB/SP) @@ -163,7 +185,7 @@ n->addable = 8; break; } - if(n->addable == 8 && !side(n)) { + if(n->addable == 8 && !indexing(n) && !side(n)){ indx(n); l = new1(OINDEX, idx.basetree, idx.regtree); l->scale = idx.scale; diff -Nru /n/sources/plan9/sys/src/cmd/cc/cc.h /sys/src/cmd/cc/cc.h --- /n/sources/plan9/sys/src/cmd/cc/cc.h Fri Aug 2 20:36:09 2013 +++ /sys/src/cmd/cc/cc.h Mon Dec 14 00:00:00 2015 @@ -32,7 +32,7 @@ #define NTERM 10 #define MAXALIGN 7 -#define SIGN(n) (1ULL<<(n-1)) +#define SIGN(n) ((uvlong)1<<(n-1)) #define MASK(n) (SIGN(n)|(SIGN(n)-1)) #define BITS 5 @@ -450,8 +450,8 @@ EXTERN long lastfield; EXTERN Type* lasttype; EXTERN long lineno; -EXTERN long nearln; EXTERN int maxinclude; +EXTERN long nearln; EXTERN int nerrors; EXTERN int newflag; EXTERN long nhunk; @@ -665,6 +665,7 @@ * sub.c */ void arith(Node*, int); +int castucom(Node*); int deadheads(Node*); Type* dotsearch(Sym*, Type*, Node*, long*); long dotoffset(Type*, Type*, Node*); diff -Nru /n/sources/plan9/sys/src/cmd/cc/com.c /sys/src/cmd/cc/com.c --- /n/sources/plan9/sys/src/cmd/cc/com.c Tue Apr 23 23:19:44 2013 +++ /sys/src/cmd/cc/com.c Mon Dec 14 00:00:00 2015 @@ -601,10 +607,8 @@ goto bad; n->type = l->type->link; if(!debug['B']) - if(l->type->down == T || l->type->down->etype == TOLD) { - nerrors--; + if(l->type->down == T || l->type->down->etype == TOLD) diag(n, "function args not checked: %F", l); - } dpcheck(n); break; @@ -1031,6 +1035,23 @@ case OASADD: ccom(l); ccom(r); + if(n->op == OASMOD || n->op == OASLMOD || n->op == OASDIV || n->op == OASLDIV) + if(r->op == OCONST){ + if(!typefd[r->type->etype] && r->vconst == 0) { + if(n->op == OASMOD || n->op == OASLMOD) + diag(n, "modulo by zero"); + else + diag(n, "divide by zero"); + r->vconst = ~0; + } + if(typefd[r->type->etype] && r->fconst == 0.) { + if(n->op == OASMOD || n->op == OASLMOD) + diag(n, "modulo by zero"); + else + diag(n, "divide by zero"); + r->fconst = 1e10; + } + } if(n->op == OASLSHR || n->op == OASASHR || n->op == OASASHL) if(r->op == OCONST) { t = n->type->width * 8; /* bits per byte */ @@ -1040,6 +1061,8 @@ break; case OCAST: + if(castucom(n)) + warn(n, "32-bit unsigned complement zero-extended to 64 bits"); ccom(l); if(l->op == OCONST) { evconst(n); diff -Nru /n/sources/plan9/sys/src/cmd/cc/dcl.c /sys/src/cmd/cc/dcl.c --- /n/sources/plan9/sys/src/cmd/cc/dcl.c Tue Apr 23 23:19:44 2013 +++ /sys/src/cmd/cc/dcl.c Mon Dec 14 00:00:00 2015 @@ -381,8 +381,15 @@ diag(a, "initialization of incompatible pointers: %s\n%T and %T", s->name, t, a->type); } - if(a->op == OADDR) + switch(a->op) { + case OADDR: a = a->left; + break; + case ONAME: + case OIND: + diag(a, "initializer is not a constant: %s", s->name); + return Z; + } goto gext; } diff -Nru /n/sources/plan9/sys/src/cmd/cc/dpchk.c /sys/src/cmd/cc/dpchk.c --- /n/sources/plan9/sys/src/cmd/cc/dpchk.c Thu Feb 25 18:36:49 2010 +++ /sys/src/cmd/cc/dpchk.c Mon Dec 14 00:00:00 2015 @@ -75,9 +75,9 @@ nstar = 0; for(;;) { s += chartorune(&c, s); - fmt += runetochar(fmt, &c); if(c == 0 || c >= nelem(flagbits)) break; + fmt += runetochar(fmt, &c); f = flagbits[c]; switch(f) { case Fnone: diff -Nru /n/sources/plan9/sys/src/cmd/cc/lex.c /sys/src/cmd/cc/lex.c --- /n/sources/plan9/sys/src/cmd/cc/lex.c Fri Aug 2 20:36:13 2013 +++ /sys/src/cmd/cc/lex.c Mon Dec 14 00:00:00 2015 @@ -161,7 +161,7 @@ int compile(char *file, char **defs, int ndef) { - char ofile[400], incfile[20]; + char ofile[400], incfile[200]; char *p, **av, opt[256]; int i, c, fd[2]; static int first = 1; @@ -199,9 +199,18 @@ setinclude(p); } else { if(systemtype(Plan9)) { - sprint(incfile, "/%s/include", thestring); + p = getenv("ccroot"); + if(p == nil) + p = ""; + snprint(incfile, sizeof(incfile), "%s/%s/include", p, thestring); setinclude(strdup(incfile)); - setinclude("/sys/include"); + snprint(incfile, sizeof(incfile), "%s/sys/include", p); + setinclude(strdup(incfile)); + if(*p != '\0') { + snprint(incfile, sizeof(incfile), "%s/include", p); + if(myaccess(incfile) >= 0) + setinclude(strdup(incfile)); + } } } if (first) diff -Nru /n/sources/plan9/sys/src/cmd/cc/macbody /sys/src/cmd/cc/macbody --- /n/sources/plan9/sys/src/cmd/cc/macbody Wed Nov 16 23:40:45 2011 +++ /sys/src/cmd/cc/macbody Mon Dec 14 00:00:00 2015 @@ -18,29 +18,47 @@ return n; } -Sym* -getsym(void) +static void +nextsym(int c) { - int c; + int c1; char *cp; - c = getnsc(); - if(!isalpha(c) && c != '_' && c < Runeself) { - unget(c); - return S; - } for(cp = symb;;) { - if(cp <= symb+NSYMB-4) - *cp++ = c; + if(c >= Runeself) { + for(c1=0;;) { + if(cp <= symb+NSYMB-UTFmax) + cp[c1++] = c; + if(fullrune(cp, c1)) + break; + c = getc(); + } + cp += c1; + }else + if(cp <= symb+NSYMB-UTFmax) + *cp++ = c; c = getc(); - if(isalnum(c) || c == '_' || c >= Runeself) + if(c >= Runeself || isalnum(c) || c == '_') continue; unget(c); break; } *cp = 0; - if(cp > symb+NSYMB-4) + if(cp > symb+NSYMB-UTFmax) yyerror("symbol too large: %s", symb); +} + +Sym* +getsym(void) +{ + int c; + + c = getnsc(); + if(c < Runeself && !isalpha(c) && c != '_') { + unget(c); + return S; + } + nextsym(c); return lookup(); } @@ -193,7 +211,7 @@ macdef(void) { Sym *s, *a; - char *args[NARG], *np, *base; + char *args[NARG], *base; int n, i, c, len, dots; int ischr; @@ -235,15 +253,9 @@ len = 1; ischr = 0; for(;;) { - if(isalpha(c) || c == '_') { - np = symb; - *np++ = c; + if(c >= Runeself || isalpha(c) || c == '_') { + nextsym(c); c = getc(); - while(isalnum(c) || c == '_') { - *np++ = c; - c = getc(); - } - *np = 0; for(i=0; iname); break; } @@ -390,7 +402,7 @@ unget(c); l = 0; cp = buf; - ecp = cp + sizeof(buf)-4; + ecp = cp + sizeof(buf)-UTFmax; arg[n++] = cp; for(;;) { if(cp >= ecp) diff -Nru /n/sources/plan9/sys/src/cmd/cc/omachcap.c /sys/src/cmd/cc/omachcap.c --- /n/sources/plan9/sys/src/cmd/cc/omachcap.c Fri Mar 24 23:10:29 2006 +++ /sys/src/cmd/cc/omachcap.c Mon Dec 14 00:00:00 2015 @@ -2,7 +2,8 @@ /* default, like old cc */ int -machcap(Node*) +machcap(Node *n) { + USED(n); return 0; } diff -Nru /n/sources/plan9/sys/src/cmd/cc/pickle.c /sys/src/cmd/cc/pickle.c --- /n/sources/plan9/sys/src/cmd/cc/pickle.c Mon Sep 17 18:53:34 2012 +++ /sys/src/cmd/cc/pickle.c Mon Dec 14 00:00:00 2015 @@ -2,12 +2,12 @@ static char *kwd[] = { - "$adt", "$aggr", "$append", "$complex", "$defn", + "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn", "$delete", "$do", "$else", "$eval", "$head", "$if", "$local", "$loop", "$return", "$tail", "$then", "$union", "$whatis", "$while", }; -static char picklestr[] = "\tpickle(s, un, "; +static char picklestr[] = "\tbp = pickle(bp, ep, un, "; static char* pmap(char *s) @@ -153,10 +153,10 @@ if(s1 == S) break; if(s == S) { - Bprint(&outbuf, "\tpickle_%s(s, un, (%s*)((char*)addr+%ld+_i*%ld));\n", + Bprint(&outbuf, "\tbp = pickle_%s(bp, ep, un, (%s*)((char*)addr+%ld+_i*%ld));\n", pmap(s1->name), pmap(s1->name), t->offset+off, t->width); } else { - Bprint(&outbuf, "\tpickle_%s(s, un, &addr->%s);\n", + Bprint(&outbuf, "\tbp = pickle_%s(bp, ep, un, &addr->%s);\n", pmap(s1->name), pmap(s->name)); } break; @@ -195,10 +195,10 @@ goto asmstr; an = pmap(s->name); - Bprint(&outbuf, "void\npickle_%s(void *s, int un, %s *addr)\n{\n\tint _i = 0;\n\n\tUSED(_i);\n", an, an); + Bprint(&outbuf, "uchar*\npickle_%s(uchar *bp, uchar *ep, int un, %s *addr)\n{\n\tint _i = 0;\n\n\tUSED(_i);\n", an, an); for(l = t->link; l != T; l = l->down) picklemember(l, 0); - Bprint(&outbuf, "}\n\n"); + Bprint(&outbuf, "\treturn bp;\n}\n\n"); break; asmstr: if(s == S) diff -Nru /n/sources/plan9/sys/src/cmd/cc/sub.c /sys/src/cmd/cc/sub.c --- /n/sources/plan9/sys/src/cmd/cc/sub.c Tue Apr 23 23:19:31 2013 +++ /sys/src/cmd/cc/sub.c Mon Dec 14 00:00:00 2015 @@ -662,7 +662,7 @@ Type *t1, *t2; int i, j, k; Node *n1; - long w; + long w, x; t1 = n->left->type; if(n->right == Z) @@ -692,7 +692,19 @@ if(n->op == OSUB) if(i == TIND && j == TIND) { w = n->right->type->link->width; - if(w < 1 || n->left->type->link == T || n->left->type->link->width < 1) + if(w < 1) { + snap(n->right->type->link); + w = n->right->type->link->width; + } + x = 0; + if(n->left->type->link != T) { + x = n->left->type->link->width; + if(x < 1) { + snap(n->left->type->link); + x = n->left->type->link->width; + } + } + if(w < 1 || x < 1) goto bad; n->type = types[ewidth[TIND] <= ewidth[TLONG]? TLONG: TVLONG]; if(1 && ewidth[TIND] > ewidth[TLONG]){ @@ -917,6 +929,10 @@ case ONOT: case OADDR: case OIND: + case OCOM: + case ONEG: + case OPOS: + case OTST: n = n->left; goto loop; @@ -949,6 +965,8 @@ case OOROR: case OCOMMA: case ODOT: + case OFAS: + case OINDEX: if(side(n->left)) break; n = n->right; @@ -960,6 +978,10 @@ case OSTRING: case OLSTRING: case ONAME: + case OREGPAIR: + case OEXREG: + case OREGISTER: + case OINDREG: return 0; } return 1; @@ -2029,4 +2051,22 @@ mixedasop(Type *l, Type *r) { return !typefd[l->etype] && typefd[r->etype]; +} + + +/* + * (uvlong)~ul creates a ul mask with top bits zero, which is usually wrong + * an explicit cast to ulong after ~ suppresses the diagnostic + */ +int +castucom(Node *r) +{ + Node *rl; + + if(r->op == OCAST && + (rl = r->left)->op == OCOM && + (r->type->etype == TVLONG || r->type->etype == TUVLONG) && + typeu[rl->type->etype] && typechl[rl->type->etype]) + return 1; + return 0; } diff -Nru /n/sources/plan9/sys/src/cmd/kc/cgen.c /sys/src/cmd/kc/cgen.c --- /n/sources/plan9/sys/src/cmd/kc/cgen.c Fri Mar 24 23:10:59 2006 +++ /sys/src/cmd/kc/cgen.c Mon Dec 14 00:00:00 2015 @@ -1,5 +1,7 @@ #include "gc.h" +static void genasop(int, Node*, Node*, Node*); + void cgen(Node *n, Node *nn) { @@ -217,6 +219,8 @@ regfree(&nod2); break; } + genasop(o, l, r, nn); + break; case OASLMUL: case OASLDIV: @@ -226,29 +230,7 @@ case OASMOD: if(l->op == OBIT) goto asbitop; - if(l->complex >= r->complex) { - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - regalloc(&nod, n, nn); - cgen(r, &nod); - } else { - regalloc(&nod, n, nn); - cgen(r, &nod); - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - } - regalloc(&nod1, n, Z); - gopcode(OAS, &nod2, Z, &nod1); - gopcode(o, &nod, &nod1, &nod); - gopcode(OAS, &nod, Z, &nod2); - regfree(&nod); - regfree(&nod1); - if(l->addable < INDEXED) - regfree(&nod2); + genasop(o, l, r, nn); break; asbitop: @@ -517,6 +499,43 @@ cursafe = curs; } +static void +genasop(int o, Node *l, Node *r, Node *nn) +{ + Node nod, nod1, nod2; + int hardleft; + + hardleft = l->addable < INDEXED || l->complex >= FNX; + if(l->complex >= r->complex) { + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + regalloc(&nod1, r, Z); + cgen(r, &nod1); + } else { + regalloc(&nod1, r, Z); + cgen(r, &nod1); + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + } + if(nod1.type == nod2.type || !typefd[nod1.type->etype]) + regalloc(&nod, &nod2, nn); + else + regalloc(&nod, &nod1, Z); + gmove(&nod2, &nod); + gopcode(o, &nod1, Z, &nod); + gmove(&nod, &nod2); + if(nn != Z) + gmove(&nod2, nn); + regfree(&nod); + regfree(&nod1); + if(hardleft) + regfree(&nod2); +} + void reglcgen(Node *t, Node *n, Node *nn) { @@ -835,12 +854,12 @@ case OSTRUCT: /* - * rewrite so lhs has no fn call + * rewrite so lhs has no side effects */ - if(nn != Z && nn->complex >= FNX) { + if(nn != Z && side(nn)) { nod1 = *n; nod1.type = typ(TIND, n->type); - regret(&nod2, &nod1); + regalloc(&nod2, &nod1, Z); lcgen(nn, &nod2); regsalloc(&nod0, &nod1); gopcode(OAS, &nod2, Z, &nod0); diff -Nru /n/sources/plan9/sys/src/cmd/kc/gc.h /sys/src/cmd/kc/gc.h --- /n/sources/plan9/sys/src/cmd/kc/gc.h Mon Mar 4 21:15:20 2013 +++ /sys/src/cmd/kc/gc.h Mon Dec 14 00:00:00 2015 @@ -119,7 +119,7 @@ }; #define R ((Reg*)0) -#define NRGN 600 +#define NRGN 1000 struct Rgn { Reg* enter; diff -Nru /sys/src/cmd/ld/Nt.c /sys/src/cmd/ld/Nt.c --- /sys/src/cmd/ld/Nt.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/Nt.c Mon Dec 14 00:00:00 2015 @@ -0,0 +1,51 @@ +#include +#include + +/* + * We can't include l.h, because Windoze wants to use some names + * like FLOAT and ABC which we declare. Define what we need here. + */ +typedef unsigned char uchar; +typedef unsigned int uint; +typedef unsigned long ulong; + +#define Chunk (1*1024*1024) + +void* +mysbrk(ulong size) +{ + void *v; + static int chunk; + static uchar *brk; + + if(chunk < size) { + chunk = Chunk; + if(chunk < size) + chunk = Chunk + size; + brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if(brk == 0) + return (void*)-1; + } + v = brk; + chunk -= size; + brk += size; + return v; +} + +double +cputime(void) +{ + return 0.0; +} + +int +fileexists(char *name) +{ + int fd; + + fd = open(name, OREAD); + if(fd < 0) + return 0; + close(fd); + return 1; +} diff -Nru /sys/src/cmd/ld/Plan9.c /sys/src/cmd/ld/Plan9.c --- /sys/src/cmd/ld/Plan9.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/Plan9.c Mon Dec 14 00:00:00 2015 @@ -0,0 +1,16 @@ +#include "l.h" + +void* +mysbrk(ulong size) +{ + return sbrk(size); +} + +int +fileexists(char *s) +{ + uchar dirbuf[400]; + + /* it's fine if stat result doesn't fit in dirbuf, since even then the file exists */ + return stat(s, dirbuf, sizeof(dirbuf)) >= 0; +} diff -Nru /sys/src/cmd/ld/Posix.c /sys/src/cmd/ld/Posix.c --- /sys/src/cmd/ld/Posix.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/Posix.c Mon Dec 14 00:00:00 2015 @@ -0,0 +1,46 @@ +#include "l.h" +#include +#include +#include +#undef getwd +#include /* For sysconf() and _SC_CLK_TCK */ + +void* +mysbrk(usize size) +{ + return (void*)sbrk(size); +} + +double +cputime(void) +{ + + struct tms tmbuf; + double ret_val; + + /* + * times() only fails if &tmbuf is invalid. + */ + (void)times(&tmbuf); + /* + * Return the total time (in system clock ticks) + * spent in user code and system + * calls by both the calling process and its children. + */ + ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime + + tmbuf.tms_cutime + tmbuf.tms_cstime); + /* + * Convert to seconds. + */ + ret_val *= sysconf(_SC_CLK_TCK); + return ret_val; + +} + +int +fileexists(char *name) +{ + struct stat sb; + + return stat(name, &sb) >= 0; +} diff -Nru /sys/src/cmd/ld/elf.c /sys/src/cmd/ld/elf.c --- /sys/src/cmd/ld/elf.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/elf.c Mon Dec 14 00:00:00 2015 @@ -0,0 +1,266 @@ +/* + * emit 32- or 64-bit elf headers for any architecture. + * this is a component of ?l. + */ +#include "l.h" + +enum { + /* offsets into string table */ + Stitext = 1, + Stidata = 7, + Stistrtab = 13, +}; + +void +elfident(int bo, int class) +{ + strnput("\177ELF", 4); /* e_ident */ + cput(class); + cput(bo); /* byte order */ + cput(1); /* version = CURRENT */ + if(debug['k']){ /* boot/embedded/standalone */ + cput(255); + cput(0); + } + else{ + cput(0); /* osabi = SYSV */ + cput(0); /* abiversion = 3 */ + } + strnput("", 7); +} + +void +elfstrtab(void) +{ + /* string table */ + cput(0); + strnput(".text", 5); /* +1 */ + cput(0); + strnput(".data", 5); /* +7 */ + cput(0); + strnput(".strtab", 7); /* +13 */ + cput(0); + cput(0); +} + +void +elf32phdr(void (*putl)(long), ulong type, ulong off, ulong vaddr, ulong paddr, + ulong filesz, ulong memsz, ulong prots, ulong align) +{ + putl(type); + putl(off); + putl(vaddr); + putl(paddr); + putl(filesz); + putl(memsz); + putl(prots); + putl(align); +} + +void +elf32shdr(void (*putl)(long), ulong name, ulong type, ulong flags, ulong vaddr, + ulong off, ulong sectsz, ulong link, ulong addnl, ulong align, + ulong entsz) +{ + putl(name); + putl(type); + putl(flags); + putl(vaddr); + putl(off); + putl(sectsz); + putl(link); + putl(addnl); + putl(align); + putl(entsz); +} + +static void +elf32sectab(void (*putl)(long)) +{ + seek(cout, HEADR+textsize+datsize+symsize, 0); + elf32shdr(putl, Stitext, Progbits, Salloc|Sexec, INITTEXT, + HEADR, textsize, 0, 0, 0x10000, 0); + elf32shdr(putl, Stidata, Progbits, Salloc|Swrite, INITDAT, + HEADR+textsize, datsize, 0, 0, 0x10000, 0); + elf32shdr(putl, Stistrtab, Strtab, 1 << 5, 0, + HEADR+textsize+datsize+symsize+3*Shdr32sz, 14, 0, 0, 1, 0); + elfstrtab(); +} + +/* if addpsects > 0, putpsects must emit exactly that many psects. */ +void +elf32(int mach, int bo, int addpsects, void (*putpsects)(Putl)) +{ + ulong phydata; + void (*putw)(long), (*putl)(long); + + if(bo == ELFDATA2MSB){ + putw = wput; + putl = lput; + }else if(bo == ELFDATA2LSB){ + putw = wputl; + putl = lputl; + }else{ + print("elf32 byte order is mixed-endian\n"); + errorexit(); + return; + } + + elfident(bo, ELFCLASS32); + putw(EXEC); + putw(mach); + putl(1L); /* version = CURRENT */ + putl(entryvalue()); /* entry vaddr */ + putl(Ehdr32sz); /* offset to first phdr */ + if(debug['S']) + putl(HEADR+textsize+datsize+symsize); /* offset to first shdr */ + else + putl(0); + putl(0L); /* flags */ + putw(Ehdr32sz); + putw(Phdr32sz); + putw(3 + addpsects); /* # of Phdrs */ + putw(Shdr32sz); + if(debug['S']){ + putw(3); /* # of Shdrs */ + putw(2); /* Shdr table index */ + }else{ + putw(0); + putw(0); + } + + /* + * could include ELF headers in text -- 8l doesn't, + * but in theory it aids demand loading. + */ + elf32phdr(putl, PT_LOAD, HEADR, INITTEXT, INITTEXTP, + textsize, textsize, R|X, INITRND); /* text */ + /* + * we need INITDATP, but it has to be computed. + * assume distance between INITTEXT & INITTEXTP is also + * correct for INITDAT and INITDATP. + */ + phydata = INITDAT - (INITTEXT - INITTEXTP); + elf32phdr(putl, PT_LOAD, HEADR+textsize, INITDAT, phydata, + datsize, datsize+bsssize, R|W|X, INITRND); /* data */ + elf32phdr(putl, NOPTYPE, HEADR+textsize+datsize, 0, 0, + symsize, lcsize, R, 4); /* symbol table */ + if (addpsects > 0) + putpsects(putl); + cflush(); + + if(debug['S']) + elf32sectab(putl); +} + +/* + * elf64 + */ + +void +elf64phdr(void (*putl)(long), void (*putll)(vlong), ulong type, uvlong off, + uvlong vaddr, uvlong paddr, uvlong filesz, uvlong memsz, ulong prots, + uvlong align) +{ + putl(type); + putl(prots); + putll(off); + putll(vaddr); + putll(paddr); + putll(filesz); + putll(memsz); + putll(align); +} + +void +elf64shdr(void (*putl)(long), void (*putll)(vlong), ulong name, ulong type, + uvlong flags, uvlong vaddr, uvlong off, uvlong sectsz, ulong link, + ulong addnl, uvlong align, uvlong entsz) +{ + putl(name); + putl(type); + putll(flags); + putll(vaddr); + putll(off); + putll(sectsz); + putl(link); + putl(addnl); + putll(align); + putll(entsz); +} + +static void +elf64sectab(void (*putl)(long), void (*putll)(vlong)) +{ + seek(cout, HEADR+textsize+datsize+symsize, 0); + elf64shdr(putl, putll, Stitext, Progbits, Salloc|Sexec, INITTEXT, + HEADR, textsize, 0, 0, 0x10000, 0); + elf64shdr(putl, putll, Stidata, Progbits, Salloc|Swrite, INITDAT, + HEADR+textsize, datsize, 0, 0, 0x10000, 0); + elf64shdr(putl, putll, Stistrtab, Strtab, 1 << 5, 0, + HEADR+textsize+datsize+symsize+3*Shdr64sz, 14, 0, 0, 1, 0); + elfstrtab(); +} + +/* if addpsects > 0, putpsects must emit exactly that many psects. */ +void +elf64(int mach, int bo, int addpsects, void (*putpsects)(Putl)) +{ + uvlong phydata; + void (*putw)(long), (*putl)(long); + void (*putll)(vlong); + + if(bo == ELFDATA2MSB){ + putw = wput; + putl = lput; + putll = llput; + }else if(bo == ELFDATA2LSB){ + putw = wputl; + putl = lputl; + putll = llputl; + }else{ + print("elf64 byte order is mixed-endian\n"); + errorexit(); + return; + } + + elfident(bo, ELFCLASS64); + putw(EXEC); + putw(mach); + putl(1L); /* version = CURRENT */ + putll(entryvalue()); /* entry vaddr */ + putll(Ehdr64sz); /* offset to first phdr */ + if(debug['S']) + putll(HEADR+textsize+datsize+symsize); /* offset to 1st shdr */ + else + putll(0); + putl(0L); /* flags */ + putw(Ehdr64sz); + putw(Phdr64sz); + putw(3 + addpsects); /* # of Phdrs */ + putw(Shdr64sz); + if(debug['S']){ + putw(3); /* # of Shdrs */ + putw(2); /* Shdr table index */ + }else{ + putw(0); + putw(0); + } + + elf64phdr(putl, putll, PT_LOAD, HEADR, INITTEXT, INITTEXTP, + textsize, textsize, R|X, INITRND); /* text */ + /* + * see 32-bit ELF case for physical data address computation. + */ + phydata = INITDAT - (INITTEXT - INITTEXTP); + elf64phdr(putl, putll, PT_LOAD, HEADR+textsize, INITDAT, phydata, + datsize, datsize+bsssize, R|W, INITRND); /* data */ + elf64phdr(putl, putll, NOPTYPE, HEADR+textsize+datsize, 0, 0, + symsize, lcsize, R, 4); /* symbol table */ + if (addpsects > 0) + putpsects(putl); + cflush(); + + if(debug['S']) + elf64sectab(putl, putll); +} diff -Nru /sys/src/cmd/ld/elf.h /sys/src/cmd/ld/elf.h --- /sys/src/cmd/ld/elf.h Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/elf.h Mon Dec 14 00:00:00 2015 @@ -0,0 +1,97 @@ +enum { + Ehdr32sz = 52, + Phdr32sz = 32, + Shdr32sz = 40, + + Ehdr64sz = 64, + Phdr64sz = 56, + Shdr64sz = 64, +}; + +/* from /sys/src/libmach/elf.h */ +enum { + /* Ehdr codes */ + MAG0 = 0, /* ident[] indexes */ + MAG1 = 1, + MAG2 = 2, + MAG3 = 3, + CLASS = 4, + DATA = 5, + VERSION = 6, + + ELFCLASSNONE = 0, /* ident[CLASS] */ + ELFCLASS32 = 1, + ELFCLASS64 = 2, + ELFCLASSNUM = 3, + + ELFDATANONE = 0, /* ident[DATA] */ + ELFDATA2LSB = 1, + ELFDATA2MSB = 2, + ELFDATANUM = 3, + + NOETYPE = 0, /* type */ + REL = 1, + EXEC = 2, + DYN = 3, + CORE = 4, + + NONE = 0, /* machine */ + M32 = 1, /* AT&T WE 32100 */ + SPARC = 2, /* Sun SPARC */ + I386 = 3, /* Intel 80386 */ + M68K = 4, /* Motorola 68000 */ + M88K = 5, /* Motorola 88000 */ + I486 = 6, /* Intel 80486 */ + I860 = 7, /* Intel i860 */ + MIPS = 8, /* Mips R2000 */ + S370 = 9, /* Amdhal */ + MIPSR4K = 10, /* Mips R4000 */ + SPARC64 = 18, /* Sun SPARC v9 */ + POWER = 20, /* PowerPC */ + POWER64 = 21, /* PowerPC64 */ + ARM = 40, /* ARM */ + AMD64 = 62, /* Amd64 */ + ARM64 = 183, /* ARM64 */ + + NO_VERSION = 0, /* version, ident[VERSION] */ + CURRENT = 1, + + /* Phdr Codes */ + NOPTYPE = 0, /* type */ + PT_LOAD = 1, + DYNAMIC = 2, + INTERP = 3, + NOTE = 4, + SHLIB = 5, + PHDR = 6, + + R = 0x4, /* flags */ + W = 0x2, + X = 0x1, + + /* Shdr Codes */ + Progbits = 1, /* section types */ + Strtab = 3, + Nobits = 8, + + Swrite = 1, /* section attributes (flags) */ + Salloc = 2, + Sexec = 4, +}; + +typedef void (*Putl)(long); + +void elf32(int mach, int bo, int addpsects, void (*putpsects)(Putl)); +void elf32phdr(void (*putl)(long), ulong type, ulong off, ulong vaddr, + ulong paddr, ulong filesz, ulong memsz, ulong prots, ulong align); +void elf32shdr(void (*putl)(long), ulong name, ulong type, ulong flags, + ulong vaddr, ulong off, ulong sectsz, ulong link, ulong addnl, + ulong align, ulong entsz); + +void elf64(int mach, int bo, int addpsects, void (*putpsects)(Putl)); +void elf64phdr(void (*putl)(long), void (*putll)(vlong), ulong type, + uvlong off, uvlong vaddr, uvlong paddr, uvlong filesz, uvlong memsz, + ulong prots, uvlong align); +void elf64shdr(void (*putl)(long), void (*putll)(vlong), ulong name, + ulong type, uvlong flags, uvlong vaddr, uvlong off, uvlong sectsz, + ulong link, ulong addnl, uvlong align, uvlong entsz); diff -Nru /sys/src/cmd/ld/falloc.c /sys/src/cmd/ld/falloc.c --- /sys/src/cmd/ld/falloc.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/falloc.c Mon Dec 14 00:00:00 2015 @@ -0,0 +1,48 @@ +#include "l.h" + +/* + * fake malloc + */ +void* +malloc(usize n) +{ + return halloc(n); +} + +void +free(void *p) +{ + USED(p); +} + +void* +calloc(usize m, usize n) +{ + void *p; + + n *= m; + p = malloc(n); + memset(p, 0, n); + return p; +} + +/* + * not used by compiler or loader, but Windows needs it + */ +void* +realloc(void *p, usize n) +{ + void *new; + + new = malloc(n); + if(new != nil && p != nil) + memmove(new, p, n); /* safe only when adjecent hunks have no gaps */ + return new; +} + +void +setmalloctag(void *v, ulong pc) +{ + USED(v); + USED(pc); +} diff -Nru /sys/src/cmd/ld/ld.h /sys/src/cmd/ld/ld.h --- /sys/src/cmd/ld/ld.h Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/ld.h Mon Dec 14 00:00:00 2015 @@ -0,0 +1,156 @@ +#include +#include +#include +#include "../ld/elf.h" + +typedef vlong int64; + +/* + * basic types in all loaders + */ + +typedef struct Adr Adr; +typedef struct Auto Auto; +typedef struct Count Count; +typedef struct Ieee Ieee; +typedef struct Prog Prog; +typedef struct Sym Sym; + +#ifndef EXTERN +#define EXTERN extern +#endif + +#define LIBNAMELEN 300 + +#define P ((Prog*)0) +#define S ((Sym*)0) +#define TNAME (curtext&&curtext->from.sym?curtext->from.sym->name:noname) + +struct Auto +{ + Sym* asym; + Auto* link; + vlong aoffset; + short type; +}; + +struct Count +{ + long count; + long outof; +}; + +enum +{ + + STRINGSZ = 200, + NHASH = 10007, + NHUNK = 100000, + MAXIO = 8192, + MAXHIST = 20, /* limit of path elements for history symbols */ +}; + +#define SIGNINTERN (1729*325*1729) /* signature of internal functions such as _div */ + +EXTERN union +{ + struct + { + uchar obuf[MAXIO]; /* output buffer */ + uchar ibuf[MAXIO]; /* input buffer */ + } u; + char dbuf[1]; +} buf; + +#define cbuf u.obuf +#define xbuf u.ibuf + +EXTERN int cbc; +EXTERN uchar* cbp; +EXTERN int cout; +EXTERN char debug[128]; +EXTERN char fnuxi4[4]; +EXTERN char fnuxi8[8]; +EXTERN Sym* hash[NHASH]; +EXTERN Sym* histfrog[MAXHIST]; +EXTERN int histfrogp; +EXTERN int histgen; +EXTERN char* library[50]; +EXTERN char* libraryobj[50]; +EXTERN int libraryp; +EXTERN int xrefresolv; +EXTERN char inuxi1[1]; +EXTERN char inuxi2[2]; +EXTERN char inuxi4[4]; +EXTERN uchar inuxi8[8]; +EXTERN char* thestring; +EXTERN char thechar; + +EXTERN int doexp, dlm; +EXTERN int imports, nimports; +EXTERN int exports, nexports; +EXTERN char* EXPTAB; +EXTERN Prog undefp; + +#define UP (&undefp) + +int Sconv(Fmt*); +void addhist(long, int); +void addlib(char*); +void addlibpath(char*); +void addlibroot(void); +vlong atolwhex(char*); +Prog* brchain(Prog*); +Prog* brloop(Prog*); +void cflush(void); +void ckoff(Sym*, long); +void collapsefrog(Sym*); +void cput(int); +void diag(char*, ...); +void errorexit(void); +double cputime(void); +void dodata(void); +void export(void); +int fileexists(char*); +int find1(long, int); +char* findlib(char*); +char* findlib(char*); +void follow(void); +void gethunk(void); +long hunkspace(void); +uchar* readsome(int, uchar*, uchar*, uchar*, int); +void* halloc(usize); +void histtoauto(void); +double ieeedtod(Ieee*); +long ieeedtof(Ieee*); +void import(void); +int isobjfile(char*); +void loadlib(void); +Sym* lookup(char*, int); +void mkfwd(void); +void* mysbrk(ulong); +void nopstat(char*, Count*); +void objfile(char*); +void patch(void); +void prasm(Prog*); +Prog* prg(void); +void readundefs(char*, int); +uchar* readsome(int, uchar*, uchar*, uchar*, int); +void readundefs(char*, int); +vlong rnd(vlong, long); +void strnput(char*, int); +void undef(void); +void undefsym(Sym*); +void xdefine(char*, int, vlong); +void xfol(Prog*); +void zerosig(char*); + +#pragma varargck type "A" int +#pragma varargck type "A" uint +#pragma varargck type "C" int +#pragma varargck type "D" Adr* +#pragma varargck type "N" Adr* +#pragma varargck type "P" Prog* +#pragma varargck type "S" char* + +#pragma varargck argpos diag 1 diff -Nru /sys/src/cmd/ld/mkcname /sys/src/cmd/ld/mkcname --- /sys/src/cmd/ld/mkcname Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/mkcname Mon Dec 14 00:00:00 2015 @@ -0,0 +1,17 @@ +ed - l.h <<'!' +v/^ C_/d +g/^ C_NCLASS/s//&,/ +g/[ ]*=.*,/s//,/ +v/,/p +,s/^ C_/ "/ +,s/,.*$/",/ +1i +char *cnames[] = +{ +. +,a +}; +. +w cnam.c +Q +! diff -Nru /sys/src/cmd/ld/mkfile /sys/src/cmd/ld/mkfile --- /sys/src/cmd/ld/mkfile Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/mkfile Mon Dec 14 00:00:00 2015 @@ -0,0 +1,2 @@ +all clean install nuke:VQ: + # diff -Nru /sys/src/cmd/ld/mod.c /sys/src/cmd/ld/mod.c --- /sys/src/cmd/ld/mod.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/mod.c Mon Dec 14 00:00:00 2015 @@ -0,0 +1,203 @@ +#include "l.h" + +void +readundefs(char *f, int t) +{ + int i, n; + Sym *s; + Biobuf *b; + char *l, buf[256], *fields[64]; + + if(f == nil) + return; + b = Bopen(f, OREAD); + if(b == nil){ + diag("could not open %s: %r", f); + errorexit(); + } + while((l = Brdline(b, '\n')) != nil){ + n = Blinelen(b); + if(n >= sizeof(buf)){ + diag("%s: line too long", f); + errorexit(); + } + memmove(buf, l, n); + buf[n-1] = '\0'; + n = getfields(buf, fields, nelem(fields), 1, " \t\r\n"); + if(n == nelem(fields)){ + diag("%s: bad format", f); + errorexit(); + } + for(i = 0; i < n; i++){ + s = lookup(fields[i], 0); + s->type = SXREF; + s->subtype = t; + if(t == SIMPORT) + nimports++; + else + nexports++; + } + } + Bterm(b); +} + +void +undefsym(Sym *s) +{ + int n; + + n = imports; + if(s->value != 0) + diag("value != 0 on SXREF"); + if(n >= 1<value = n<type = SUNDEF; + imports++; +} + +void +zerosig(char *sp) +{ + Sym *s; + + s = lookup(sp, 0); + s->sig = 0; +} + +void +import(void) +{ + int i; + Sym *s; + + for(i = 0; i < NHASH; i++) + for(s = hash[i]; s != S; s = s->link) + if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){ + undefsym(s); + Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, (vlong)s->value); + } +} + +void +ckoff(Sym *s, long v) +{ + if(v < 0 || v >= 1<name); +} + +static Prog* +newdata(Sym *s, int o, int w, int t) +{ + Prog *p; + + p = prg(); + p->link = datap; + datap = p; + p->as = ADATA; + p->reg = w; + p->from.type = D_OREG; + p->from.name = t; + p->from.sym = s; + p->from.offset = o; + p->to.type = D_CONST; + p->to.name = D_NONE; + return p; +} + +void +export(void) +{ + int i, j, n, off, nb, sv, ne; + Sym *s, *et, *str, **esyms; + Prog *p; + char buf[NSNAME], *t; + + n = 0; + for(i = 0; i < NHASH; i++) + for(s = hash[i]; s != S; s = s->link) + if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT)) + n++; + esyms = malloc(n*sizeof(Sym*)); + ne = n; + n = 0; + for(i = 0; i < NHASH; i++) + for(s = hash[i]; s != S; s = s->link) + if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT)) + esyms[n++] = s; + for(i = 0; i < ne-1; i++) + for(j = i+1; j < ne; j++) + if(strcmp(esyms[i]->name, esyms[j]->name) > 0){ + s = esyms[i]; + esyms[i] = esyms[j]; + esyms[j] = s; + } + + nb = 0; + off = 0; + et = lookup(EXPTAB, 0); + if(et->type != 0 && et->type != SXREF) + diag("%s already defined", EXPTAB); + et->type = SDATA; + str = lookup(".string", 0); + if(str->type == 0) + str->type = SDATA; + sv = str->value; + for(i = 0; i < ne; i++){ + s = esyms[i]; + Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type); + + /* signature */ + p = newdata(et, off, sizeof(long), D_EXTERN); + off += sizeof(long); + p->to.offset = s->sig; + + /* address */ + p = newdata(et, off, sizeof(long), D_EXTERN); + off += sizeof(long); + p->to.name = D_EXTERN; + p->to.sym = s; + + /* string */ + t = s->name; + n = strlen(t)+1; + for(;;){ + buf[nb++] = *t; + sv++; + if(nb >= NSNAME){ + p = newdata(str, sv-NSNAME, NSNAME, D_STATIC); + p->to.type = D_SCONST; + p->to.sval = malloc(NSNAME); + memmove(p->to.sval, buf, NSNAME); + nb = 0; + } + if(*t++ == 0) + break; + } + + /* name */ + p = newdata(et, off, sizeof(long), D_EXTERN); + off += sizeof(long); + p->to.name = D_STATIC; + p->to.sym = str; + p->to.offset = sv-n; + } + + if(nb > 0){ + p = newdata(str, sv-nb, nb, D_STATIC); + p->to.type = D_SCONST; + p->to.sval = malloc(NSNAME); + memmove(p->to.sval, buf, nb); + } + + for(i = 0; i < 3; i++){ + newdata(et, off, sizeof(long), D_EXTERN); + off += sizeof(long); + } + et->value = off; + if(sv == 0) + sv = 1; + str->value = sv; + exports = ne; + free(esyms); +} diff -Nru /sys/src/cmd/ld/pass.c /sys/src/cmd/ld/pass.c --- /sys/src/cmd/ld/pass.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/pass.c Mon Dec 14 00:00:00 2015 @@ -0,0 +1,381 @@ +#include "l.h" + +void +dodata(void) +{ + int i, t; + Sym *s; + Prog *p; + long orig, v; + + if(debug['v']) + Bprint(&bso, "%5.2f dodata\n", cputime()); + Bflush(&bso); + for(p = datap; p != P; p = p->link) { + s = p->from.sym; + if(p->as == ADYNT || p->as == AINIT) + s->value = dtype; + if(s->type == SBSS) + s->type = SDATA; + if(s->type != SDATA) + diag("initialize non-data (%d): %s\n%P", + s->type, s->name, p); + v = p->from.offset + p->reg; + if(v > s->value) + diag("initialize bounds (%lld): %s\n%P", + (vlong)s->value, s->name, p); + } + + if(debug['t']) { + /* + * pull out string constants + */ + for(p = datap; p != P; p = p->link) { + s = p->from.sym; + if(p->to.type == D_SCONST) + s->type = SSTRING; + } + } + + /* + * pass 1 + * assign 'small' variables to data segment + * (rationale is that data segment is more easily + * addressed through offset on REGSB) + */ + orig = 0; + for(i=0; ilink) { + t = s->type; + if(t != SDATA && t != SBSS) + continue; + v = s->value; + if(v == 0) { + diag("%s: no size", s->name); + v = 1; + } + v = rnd(v, 4); + s->value = v; + if(v > MINSIZ) + continue; + if(v >= 16) + orig = rnd(orig, 16); + else if(v >= 8) + orig = rnd(orig, 8); + s->value = orig; + orig += v; + s->type = SDATA1; + } + + /* + * pass 2 + * assign large 'data' variables to data segment + */ + for(i=0; ilink) { + t = s->type; + if(t != SDATA) { + if(t == SDATA1) + s->type = SDATA; + continue; + } + v = s->value; + if(v >= 16) + orig = rnd(orig, 16); + else if(v >= 8) + orig = rnd(orig, 8); + s->value = orig; + orig += v; + } + + while(orig & 7) + orig++; + datsize = orig; + + /* + * pass 3 + * everything else to bss segment + */ + for(i=0; ilink) { + if(s->type != SBSS) + continue; + v = s->value; + if(v >= 16) + orig = rnd(orig, 16); + else if(v >= 8) + orig = rnd(orig, 8); + s->value = orig; + orig += v; + } + while(orig & 7) + orig++; + bsssize = orig-datsize; + + xdefine("setSB", SDATA, 0L); + xdefine("bdata", SDATA, 0L); + xdefine("edata", SDATA, datsize); + xdefine("end", SBSS, datsize+bsssize); + xdefine("etext", STEXT, 0L); +} + +Prog* +brchain(Prog *p) +{ + int i; + + for(i=0; i<20; i++) { + if(p == P || !isbranch(p->as)) + return p; + p = p->cond; + } + return P; +} + +void +follow(void) +{ + if(debug['v']) + Bprint(&bso, "%5.2f follow\n", cputime()); + Bflush(&bso); + + firstp = prg(); + lastp = firstp; + xfol(textp); + + firstp = firstp->link; + lastp->link = P; +} + +void +xfol(Prog *p) +{ + Prog *q, *r; + int a, i; + +loop: + if(p == P) + return; + a = p->as; + if(a == ATEXT) + curtext = p; + if(isbranch(a)) { + q = p->cond; + if(q != P) { + p->mark |= FOLL; + p = q; + if(!(p->mark & FOLL)) + goto loop; + } + } + if(p->mark & FOLL) { + for(i=0,q=p; i<4; i++,q=q->link) { + if(q == lastp) + break; + a = q->as; + if(a == ANOP) { + i--; + continue; + } + if(isbranch(a) || isreturn(a)) + goto copy; + if(q->cond == nil || (q->cond->mark&FOLL)) + continue; + if(a != ABEQ && a != ABNE) + continue; + copy: + for(;;) { + r = prg(); + *r = *p; + if(!(r->mark&FOLL)) + print("cant happen 1\n"); + r->mark |= FOLL; + if(p != q) { + p = p->link; + lastp->link = r; + lastp = r; + continue; + } + lastp->link = r; + lastp = r; + if(isbranch(a) || isreturn(a)) + return; + r->as = a == ABNE? ABEQ: ABNE; + r->cond = p->link; + r->link = p->cond; + if(!(r->link->mark&FOLL)) + xfol(r->link); + if(!(r->cond->mark&FOLL)) + print("cant happen 2\n"); + return; + } + } + a = branchop(); + q = prg(); + q->as = a; + q->line = p->line; + q->to.type = D_BRANCH; + q->to.offset = p->pc; + q->cond = p; + p = q; + } + p->mark |= FOLL; + lastp->link = p; + lastp = p; + if(isbranch(a) || isreturn(a)) + return; + if(p->cond != P) + if(!iscall(a) && p->link != P) { + q = brchain(p->link); + if(canfollow(a)) + if(q != P && (q->mark&FOLL)) { + p->as = relinv(a); + p->link = p->cond; + p->cond = q; + } + xfol(p->link); + q = brchain(p->cond); + if(q == P) + q = p->cond; + if(q->mark&FOLL) { + p->cond = q; + return; + } + p = q; + goto loop; + } + p = p->link; + goto loop; +} + +void +patch(void) +{ + long c, vexit; + Prog *p, *q; + Sym *s; + int a; + + if(debug['v']) + Bprint(&bso, "%5.2f patch\n", cputime()); + Bflush(&bso); + mkfwd(); + s = lookup("exit", 0); + vexit = s->value; + for(p = firstp; p != P; p = p->link) { + a = p->as; + if(a == ATEXT) + curtext = p; + if((iscall(a) || isbranch(a) || isreturn(a)) && + p->to.type != D_BRANCH && p->to.sym != S) { + s = p->to.sym; + switch(s->type) { + default: + diag("undefined: %s\n%P", s->name, p); + s->type = STEXT; + s->value = vexit; + break; + case STEXT: + p->to.offset = s->value; + break; + case SUNDEF: + if(!iscall(p->as)) + diag("help: SUNDEF in AB || ARET"); + p->to.offset = 0; + p->cond = UP; + break; + } + p->to.type = D_BRANCH; + } + if(p->cond == UP) + continue; + if(p->to.type == D_BRANCH) + c = p->to.offset; + else if(p->from.type == D_BRANCH) + c = p->from.offset; + else + continue; + for(q = firstp; q != P;) { + if(q->forwd != P) + if(c >= q->forwd->pc) { + q = q->forwd; + continue; + } + if(c == q->pc) + break; + q = q->link; + } + if(q == P) { + diag("branch out of range %ld\n%P", c, p); + p->to.type = D_NONE; + } + p->cond = q; + } + + for(p = firstp; p != P; p = p->link) { + if(p->as == ATEXT) + curtext = p; + if(p->cond != P && p->cond != UP) { + p->cond = brloop(p->cond); + if(p->cond != P){ + if(p->to.type == D_BRANCH) + p->to.offset = p->cond->pc; + if(p->from.type == D_BRANCH) + p->from.offset = p->cond->pc; + } + } + } +} + +#define LOG 6 +void +mkfwd(void) +{ + Prog *p; + long dwn[LOG], cnt[LOG], i; + Prog *lst[LOG]; + + for(i=0; ilink) { + if(p->as == ATEXT) + curtext = p; + i--; + if(i < 0) + i = LOG-1; + p->forwd = P; + dwn[i]--; + if(dwn[i] <= 0) { + dwn[i] = cnt[i]; + if(lst[i] != P) + lst[i]->forwd = p; + lst[i] = p; + } + } +} + +Prog* +brloop(Prog *p) +{ + Prog *q; + int c; + + for(c=0; p!=P;) { + if(!isbranch(p->as)) + return p; + q = p->cond; + if(q <= p) { + c++; + if(q == p || c > 5000) + break; + } + p = q; + } + return P; +} diff -Nru /sys/src/cmd/ld/pobj.c /sys/src/cmd/ld/pobj.c --- /sys/src/cmd/ld/pobj.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/pobj.c Mon Dec 14 00:00:00 2015 @@ -0,0 +1,485 @@ +#include "l.h" +#include + +char *noname = ""; +char symname[] = SYMDEF; + +char** libdir; +int nlibdir = 0; +static int maxlibdir = 0; + +int +isobjfile(char *f) +{ + int n, v; + Biobuf *b; + char buf1[5], buf2[SARMAG]; + + b = Bopen(f, OREAD); + if(b == nil) + return 0; + n = Bread(b, buf1, 5); + if(n == 5 && (buf1[2] == 1 && buf1[3] == '<' || buf1[3] == 1 && buf1[4] == '<')) + v = 1; /* good enough for our purposes */ + else{ + Bseek(b, 0, 0); + n = Bread(b, buf2, SARMAG); + v = n == SARMAG && strncmp(buf2, ARMAG, SARMAG) == 0; + } + Bterm(b); + return v; +} + +void +loadlib(void) +{ + int i; + long h; + Sym *s; + +loop: + xrefresolv = 0; + for(i=0; ilink) + if(s->type == SXREF) + goto loop; +} + +void +objfile(char *file) +{ + long off, esym, cnt, l; + int f, work; + Sym *s; + char magbuf[SARMAG]; + char name[LIBNAMELEN], pname[LIBNAMELEN]; + struct ar_hdr arhdr; + char *e, *start, *stop; + + if(debug['v']) + Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); + Bflush(&bso); + if(file[0] == '-' && file[1] == 'l') { + snprint(pname, sizeof(pname), "lib%s.a", file+2); + e = findlib(pname); + if(e == nil) { + diag("cannot find library: %s", file); + errorexit(); + } + snprint(name, sizeof(name), "%s/%s", e, pname); + file = name; + } + f = open(file, 0); + if(f < 0) { + diag("cannot open %s: %r", file); + errorexit(); + } + l = read(f, magbuf, SARMAG); + if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ + /* load it as a regular file */ + l = seek(f, 0L, 2); + seek(f, 0L, 0); + ldobj(f, l, file); + close(f); + return; + } + + if(debug['v']) + Bprint(&bso, "%5.2f ldlib: %s\n", cputime(), file); + l = read(f, &arhdr, SAR_HDR); + if(l != SAR_HDR) { + diag("%s: short read on archive file symbol header", file); + goto out; + } + if(strncmp(arhdr.name, symname, strlen(symname))) { + diag("%s: first entry not symbol header", file); + goto out; + } + + esym = SARMAG + SAR_HDR + atolwhex(arhdr.size); + off = SARMAG + SAR_HDR; + + /* + * just bang the whole symbol file into memory + */ + seek(f, off, 0); + cnt = esym - off; + start = malloc(cnt + 10); + cnt = read(f, start, cnt); + if(cnt <= 0){ + close(f); + return; + } + stop = &start[cnt]; + memset(stop, 0, 10); + + work = 1; + while(work){ + if(debug['v']) + Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); + Bflush(&bso); + work = 0; + for(e = start; e < stop; e = strchr(e+5, 0) + 1) { + s = lookup(e+5, 0); + if(s->type != SXREF) + continue; + sprint(pname, "%s(%s)", file, s->name); + if(debug['v']) + Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); + Bflush(&bso); + l = e[1] & 0xff; + l |= (e[2] & 0xff) << 8; + l |= (e[3] & 0xff) << 16; + l |= (e[4] & 0xff) << 24; + seek(f, l, 0); + l = read(f, &arhdr, SAR_HDR); + if(l != SAR_HDR) + goto bad; + if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) + goto bad; + l = atolwhex(arhdr.size); + ldobj(f, l, pname); + if(s->type == SXREF) { + diag("%s: failed to load: %s", file, s->name); + errorexit(); + } + work = 1; + xrefresolv = 1; + } + } + return; + +bad: + diag("%s: bad or out of date archive", file); +out: + close(f); +} + +void +addlibpath(char *arg) +{ + char **p; + + if(nlibdir >= maxlibdir) { + if(maxlibdir == 0) + maxlibdir = 8; + else + maxlibdir *= 2; + p = malloc(maxlibdir*sizeof(*p)); + if(p == nil) { + diag("out of memory"); + errorexit(); + } + memmove(p, libdir, nlibdir*sizeof(*p)); + free(libdir); + libdir = p; + } + libdir[nlibdir++] = strdup(arg); +} + +char* +findlib(char *file) +{ + int i; + char name[LIBNAMELEN]; + + for(i = 0; i < nlibdir; i++) { + snprint(name, sizeof(name), "%s/%s", libdir[i], file); + if(fileexists(name)) + return libdir[i]; + } + return nil; +} + +void +addlibroot(void) +{ + char *a; + char name[LIBNAMELEN]; + + a = getenv("ccroot"); + if(a != nil && *a != '\0') { + if(!fileexists(a)) { + diag("nonexistent $ccroot: %s", a); + errorexit(); + } + }else + a = ""; + snprint(name, sizeof(name), "%s/%s/lib", a, thestring); + addlibpath(name); +} + +void +addlib(char *obj) +{ + char fn1[LIBNAMELEN], fn2[LIBNAMELEN], comp[LIBNAMELEN], *p, *name; + int i, search; + + if(histfrogp <= 0) + return; + + name = fn1; + search = 0; + if(histfrog[0]->name[1] == '/') { + sprint(name, ""); + i = 1; + } else if(histfrog[0]->name[1] == '.') { + sprint(name, "."); + i = 0; + } else { + sprint(name, ""); + i = 0; + search = 1; + } + + for(; iname+1); + for(;;) { + p = strstr(comp, "$O"); + if(p == 0) + break; + memmove(p+1, p+2, strlen(p+2)+1); + p[0] = thechar; + } + for(;;) { + p = strstr(comp, "$M"); + if(p == 0) + break; + if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) { + diag("library component too long"); + return; + } + memmove(p+strlen(thestring), p+2, strlen(p+2)+1); + memmove(p, thestring, strlen(thestring)); + } + if(strlen(fn1) + strlen(comp) + 3 >= sizeof(fn1)) { + diag("library component too long"); + return; + } + if(i > 0 || !search) + strcat(fn1, "/"); + strcat(fn1, comp); + } + + cleanname(name); + + if(search){ + p = findlib(name); + if(p != nil){ + snprint(fn2, sizeof(fn2), "%s/%s", p, name); + name = fn2; + } + } + + for(i=0; iname = malloc(2*(histfrogp+1) + 1); + + u->asym = s; + u->type = type; + u->aoffset = line; + u->link = curhist; + curhist = u; + + j = 1; + for(i=0; ivalue; + s->name[j+0] = k>>8; + s->name[j+1] = k; + j += 2; + } +} + +void +histtoauto(void) +{ + Auto *l; + + while((l = curhist) != nil) { + curhist = l->link; + l->link = curauto; + curauto = l; + } +} + +void +collapsefrog(Sym *s) +{ + int i; + + /* + * bad encoding of path components only allows + * MAXHIST components. if there is an overflow, + * first try to collapse xxx/.. + */ + for(i=1; iname+1, "..") == 0) { + memmove(histfrog+i-1, histfrog+i+1, + (histfrogp-i-1)*sizeof(histfrog[0])); + histfrogp--; + goto out; + } + + /* + * next try to collapse . + */ + for(i=0; iname+1, ".") == 0) { + memmove(histfrog+i, histfrog+i+1, + (histfrogp-i-1)*sizeof(histfrog[0])); + goto out; + } + + /* + * last chance, just truncate from front + */ + memmove(histfrog+0, histfrog+1, + (histfrogp-1)*sizeof(histfrog[0])); + +out: + histfrog[histfrogp-1] = s; +} + +uchar* +readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) +{ + int n; + + n = stop - good; + memmove(buf, good, stop - good); + stop = buf + n; + n = MAXIO - n; + if(n > max) + n = max; + n = read(f, stop, n); + if(n <= 0) + return 0; + return stop + n; +} + +Sym* +lookup(char *symb, int v) +{ + Sym *s; + char *p; + long h; + int c, l; + + h = v; + for(p=symb; c = *p; p++) + h = h+h+h + c; + l = (p - symb) + 1; + if(h < 0) + h = ~h; + h %= NHASH; + for(s = hash[h]; s != S; s = s->link) + if(s->version == v) + if(memcmp(s->name, symb, l) == 0) + return s; + + s = halloc(sizeof(Sym)); + s->name = malloc(l + 1); + memmove(s->name, symb, l); + + s->link = hash[h]; + s->type = 0; + s->version = v; + s->value = 0; + s->sig = 0; + hash[h] = s; + return s; +} + +int +find1(long l, int c) +{ + char *p; + int i; + + p = (char*)&l; + for(i=0; i<4; i++) + if(*p++ == c) + return i; + return 0; +} + +long +ieeedtof(Ieee *ieeep) +{ + int exp; + long v; + + if(ieeep->h == 0) + return 0; + exp = (ieeep->h>>20) & ((1L<<11)-1L); + exp -= (1L<<10) - 2L; + v = (ieeep->h & 0xfffffL) << 3; + v |= (ieeep->l >> 29) & 0x7L; + if((ieeep->l >> 28) & 1) { + v++; + if(v & 0x800000L) { + v = (v & 0x7fffffL) >> 1; + exp++; + } + } + if(exp <= -126 || exp >= 130) + diag("double fp to single fp overflow"); + v |= ((exp + 126) & 0xffL) << 23; + v |= ieeep->h & 0x80000000L; + return v; +} + +double +ieeedtod(Ieee *ieeep) +{ + Ieee e; + double fr; + int exp; + + if(ieeep->h & (1L<<31)) { + e.h = ieeep->h & ~(1L<<31); + e.l = ieeep->l; + return -ieeedtod(&e); + } + if(ieeep->l == 0 && ieeep->h == 0) + return 0; + fr = ieeep->l & ((1L<<16)-1L); + fr /= 1L<<16; + fr += (ieeep->l>>16) & ((1L<<16)-1L); + fr /= 1L<<16; + fr += (ieeep->h & (1L<<20)-1L) | (1L<<20); + fr /= 1L<<21; + exp = (ieeep->h>>20) & ((1L<<11)-1L); + exp -= (1L<<10) - 2L; + return ldexp(fr, exp); +} diff -Nru /sys/src/cmd/ld/sub.c /sys/src/cmd/ld/sub.c --- /sys/src/cmd/ld/sub.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/ld/sub.c Mon Dec 14 00:00:00 2015 @@ -0,0 +1,264 @@ +#include "l.h" + +static usize nhunk; +static usize tothunk; +static char* hunk; + +void +diag(char *fmt, ...) +{ + char buf[STRINGSZ], *tn; + va_list arg; + + tn = "??none??"; + if(curtext != P && curtext->from.sym != S) + tn = curtext->from.sym->name; + va_start(arg, fmt); + vseprint(buf, buf+sizeof(buf), fmt, arg); + va_end(arg); + print("%s: %s\n", tn, buf); + + nerrors++; + if(nerrors > 10) { + print("too many errors\n"); + errorexit(); + } +} + +void +errorexit(void) +{ + + if(nerrors) { + if(cout >= 0) + remove(outfile); + exits("error"); + } + exits(0); +} + +void +prasm(Prog *p) +{ + print("%P\n", p); +} + +int +Sconv(Fmt *fp) +{ + int i, c; + char str[STRINGSZ], *p, *a; + + a = va_arg(fp->args, char*); + p = str; + for(i=0; i= 'a' && c <= 'z' || + c >= 'A' && c <= 'Z' || + c >= '0' && c <= '9' || + c == ' ' || c == '%') { + *p++ = c; + continue; + } + *p++ = '\\'; + switch(c) { + case 0: + *p++ = 'z'; + continue; + case '\\': + case '"': + *p++ = c; + continue; + case '\n': + *p++ = 'n'; + continue; + case '\t': + *p++ = 't'; + continue; + } + *p++ = (c>>6) + '0'; + *p++ = ((c>>3) & 7) + '0'; + *p++ = (c & 7) + '0'; + } + *p = 0; + return fmtstrcpy(fp, str); +} + +void +nopstat(char *f, Count *c) +{ + if(c->outof) + Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f, + c->outof - c->count, c->outof, + (double)(c->outof - c->count)/c->outof); +} + +void +xdefine(char *p, int t, vlong v) +{ + Sym *s; + + s = lookup(p, 0); + if(s->type == 0 || s->type == SXREF) { + s->type = t; + s->value = v; + } +} + +void +undef(void) +{ + int i; + Sym *s; + + for(i=0; ilink) + if(s->type == SXREF) + diag("%s: not defined", s->name); +} + +vlong +atolwhex(char *s) +{ + vlong n; + int f; + + n = 0; + f = 0; + while(*s == ' ' || *s == '\t') + s++; + if(*s == '-' || *s == '+') { + if(*s++ == '-') + f = 1; + while(*s == ' ' || *s == '\t') + s++; + } + if(s[0]=='0' && s[1]){ + if(s[1]=='x' || s[1]=='X'){ + s += 2; + for(;;){ + if(*s >= '0' && *s <= '9') + n = n*16 + *s++ - '0'; + else if(*s >= 'a' && *s <= 'f') + n = n*16 + *s++ - 'a' + 10; + else if(*s >= 'A' && *s <= 'F') + n = n*16 + *s++ - 'A' + 10; + else + break; + } + } else + while(*s >= '0' && *s <= '7') + n = n*8 + *s++ - '0'; + } else + while(*s >= '0' && *s <= '9') + n = n*10 + *s++ - '0'; + if(f) + n = -n; + return n; +} + +vlong +rnd(vlong v, long r) +{ + long c; + + if(r <= 0) + return v; + v += r - 1; + c = v % r; + if(c < 0) + c += r; + v -= c; + return v; +} + +Prog* +prg(void) +{ + Prog *p; + + while(nhunk < sizeof(Prog)) + gethunk(); + p = (Prog*)hunk; + nhunk -= sizeof(Prog); + hunk += sizeof(Prog); + + *p = zprg; + return p; +} + +void* +halloc(usize n) +{ + void *p; + + n = (n+7)&~7; + while(nhunk < n) + gethunk(); + p = hunk; + nhunk -= n; + hunk += n; + return p; +} + +void +gethunk(void) +{ + char *h; + long nh; + + nh = NHUNK; + if(tothunk >= 5L*NHUNK) { + nh = 5L*NHUNK; + if(tothunk >= 25L*NHUNK) + nh = 25L*NHUNK; + } + h = mysbrk(nh); + if(h == (void*)-1) { + diag("out of memory"); + errorexit(); + } + + hunk = h; + nhunk = nh; + tothunk += nh; +} + +long +hunkspace(void) +{ + return tothunk; +} + +void +strnput(char *s, int n) +{ + for(; *s; s++){ + cput(*s); + n--; + } + for(; n > 0; n--) + cput(0); +} + +void +cput(int c) +{ + cbp[0] = c; + cbp++; + cbc--; + if(cbc <= 0) + cflush(); +} + +void +cflush(void) +{ + int n; + + n = sizeof(buf.cbuf) - cbc; + if(n) + write(cout, buf.cbuf, n); + cbp = buf.cbuf; + cbc = sizeof(buf.cbuf); +} diff -Nru /n/sources/plan9/sys/src/cmd/qc/cgen.c /sys/src/cmd/qc/cgen.c --- /n/sources/plan9/sys/src/cmd/qc/cgen.c Tue Jul 7 16:35:54 2009 +++ /sys/src/cmd/qc/cgen.c Mon Dec 14 00:00:00 2015 @@ -4,6 +4,7 @@ static void testv(Node*, int); static void cgen64(Node*, Node*); static int isvconstable(int, vlong); +static void genasop(int, Node*, Node*, Node*); void cgen(Node *n, Node *nn) @@ -255,6 +256,8 @@ regfree(&nod2); break; } + genasop(o, l, r, nn); + break; case OASLMUL: case OASLDIV: @@ -264,31 +267,7 @@ case OASMOD: if(l->op == OBIT) goto asbitop; - if(l->complex >= r->complex) { - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - regalloc(&nod, r, Z); - cgen(r, &nod); - } else { - regalloc(&nod, r, Z); - cgen(r, &nod); - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - } - regalloc(&nod1, n, nn); - gopcode(OAS, &nod2, Z, &nod1); - gopcode(o, &nod, Z, &nod1); - gopcode(OAS, &nod1, Z, &nod2); - if(nn != Z) - gopcode(OAS, &nod1, Z, nn); - regfree(&nod); - regfree(&nod1); - if(l->addable < INDEXED) - regfree(&nod2); + genasop(o, l, r, nn); break; asbitop: @@ -559,6 +538,43 @@ break; } cursafe = curs; +} + +static void +genasop(int o, Node *l, Node *r, Node *nn) +{ + Node nod, nod1, nod2; + int hardleft; + + hardleft = l->addable < INDEXED || l->complex >= FNX; + if(l->complex >= r->complex) { + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + regalloc(&nod1, r, Z); + cgen(r, &nod1); + } else { + regalloc(&nod1, r, Z); + cgen(r, &nod1); + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + } + if(nod1.type == nod2.type || !typefd[nod1.type->etype]) + regalloc(&nod, &nod2, nn); + else + regalloc(&nod, &nod1, Z); + gmove(&nod2, &nod); + gopcode(o, &nod1, Z, &nod); + gmove(&nod, &nod2); + if(nn != Z) + gmove(&nod2, nn); + regfree(&nod); + regfree(&nod1); + if(hardleft) + regfree(&nod2); } void diff -Nru /n/sources/plan9/sys/src/cmd/qc/gc.h /sys/src/cmd/qc/gc.h --- /n/sources/plan9/sys/src/cmd/qc/gc.h Mon Mar 4 21:15:21 2013 +++ /sys/src/cmd/qc/gc.h Mon Dec 14 00:00:00 2015 @@ -124,7 +124,7 @@ }; #define R ((Reg*)0) -#define NRGN 600 +#define NRGN 1000 struct Rgn { Reg* enter; diff -Nru /n/sources/plan9/sys/src/cmd/qc/machcap.c /sys/src/cmd/qc/machcap.c --- /n/sources/plan9/sys/src/cmd/qc/machcap.c Tue Jul 7 16:35:25 2009 +++ /sys/src/cmd/qc/machcap.c Mon Dec 14 00:00:00 2015 @@ -18,10 +18,12 @@ case OMUL: case OLMUL: - case OASMUL: case OASLMUL: return 1; + case OASMUL: + return !mixedasop(n->type, n->right->type); + case OLSHR: case OASHR: case OASHL: @@ -58,6 +60,8 @@ case OASADD: case OASSUB: + return !mixedasop(n->type, n->right->type); + case OASAND: case OASOR: case OASXOR: diff -Nru /n/sources/plan9/sys/src/cmd/qc/txt.c /sys/src/cmd/qc/txt.c --- /n/sources/plan9/sys/src/cmd/qc/txt.c Thu Mar 8 05:42:57 2012 +++ /sys/src/cmd/qc/txt.c Mon Dec 14 00:00:00 2015 @@ -622,12 +622,86 @@ regfree(&nod3); } +static void +floattofix(Node *f, Node *t) +{ + Node nod, fxrat; + + regalloc(&nod, f, Z); + regsalloc(&fxrat, &fconstnode); + gins(AFCTIWZ, f, &nod); + gins(AFMOVD, &nod, &fxrat); + regfree(&nod); + fxrat.type = nodrat->type; + fxrat.etype = nodrat->etype; + fxrat.xoffset += 4; + gins(AMOVW, &fxrat, t); + gmove(t, t); +} + +static void +fixtofloat(Node *f, Node *t) +{ + int a, ft, tt; + Prog *p1; + Node nod, fxc0, fxc1, fxc2, fxrat; + + ft = f->type->etype; + tt = t->type->etype; + + /* + * rat[0] = 0x43300000; rat[1] = f^0x80000000; + * t = *(double*)rat - FREGCVI; + * is-unsigned(t) => if(t<0) t += 2^32; + * could be streamlined for int-to-float + */ + regalloc(&fxc0, f, Z); + regalloc(&fxc2, f, Z); + regsalloc(&fxrat, &fconstnode); /* should be type float */ + gins(AMOVW, nodconst(0x43300000L), &fxc0); + gins(AMOVW, f, &fxc2); + gins(AMOVW, &fxc0, &fxrat); + gins(AXOR, nodconst(0x80000000L), &fxc2); + fxc1 = fxrat; + fxc1.type = nodrat->type; + fxc1.etype = nodrat->etype; + fxc1.xoffset += SZ_LONG; + gins(AMOVW, &fxc2, &fxc1); + regfree(&fxc2); + regfree(&fxc0); + regalloc(&nod, t, t); /* should be type float */ + gins(AFMOVD, &fxrat, &nod); + nodreg(&fxc1, t, NREG+FREGCVI); + gins(AFSUB, &fxc1, &nod); + a = AFMOVD; + if(tt == TFLOAT) + a = AFRSP; + gins(a, &nod, t); + regfree(&nod); + if(ft == TULONG) { + regalloc(&nod, t, Z); + gins(AFCMPU, t, Z); + p->to.type = D_FREG; + p->to.reg = FREGZERO; + gins(ABGE, Z, Z); + p1 = p; + if(tt == TFLOAT) { + gins(AFMOVS, nodfconst(4294967296.), &nod); + gins(AFADDS, &nod, t); + } else { + gins(AFMOVD, nodfconst(4294967296.), &nod); + gins(AFADD, &nod, t); + } + patch(p1, pc); + regfree(&nod); + } +} + void gmove(Node *f, Node *t) { int ft, tt, a; - Node nod, fxc0, fxc1, fxc2, fxrat; - Prog *p1; + Node nod; double d; ft = f->type->etype; @@ -727,7 +801,7 @@ break; } if(typev[ft]) { - if(typev[tt]) { + if(typev[tt] || typefd[tt]) { regalloc(&nod, f, t); /* low order first, because its value will be used first */ f->xoffset += SZ_LONG; @@ -832,16 +906,11 @@ case TCHAR: case TUCHAR: /* BUG: not right for unsigned long */ - regalloc(&nod, f, Z); /* should be type float */ - regsalloc(&fxrat, &fconstnode); - gins(AFCTIWZ, f, &nod); - gins(AFMOVD, &nod, &fxrat); - regfree(&nod); - fxrat.type = nodrat->type; - fxrat.etype = nodrat->etype; - fxrat.xoffset += 4; - gins(AMOVW, &fxrat, t); - gmove(t, t); + floattofix(f, t); + return; + case TVLONG: + case TUVLONG: + diag(f, "unimplemented double->vlong"); return; } break; @@ -853,7 +922,8 @@ switch(tt) { case TDOUBLE: case TFLOAT: - goto fxtofl; + fixtofloat(f, t); + return; case TINT: case TUINT: case TLONG: @@ -871,7 +941,8 @@ switch(tt) { case TDOUBLE: case TFLOAT: - goto fxtofl; + fixtofloat(f, t); + return; case TINT: case TUINT: case TLONG: @@ -891,7 +962,8 @@ switch(tt) { case TDOUBLE: case TFLOAT: - goto fxtofl; + fixtofloat(f, t); + return; case TINT: case TUINT: case TLONG: @@ -911,7 +983,8 @@ switch(tt) { case TDOUBLE: case TFLOAT: - goto fxtofl; + fixtofloat(f, t); + return; case TINT: case TUINT: case TLONG: @@ -931,58 +1004,7 @@ switch(tt) { case TDOUBLE: case TFLOAT: - fxtofl: - /* - * rat[0] = 0x43300000; rat[1] = f^0x80000000; - * t = *(double*)rat - FREGCVI; - * is-unsigned(t) => if(t<0) t += 2^32; - * could be streamlined for int-to-float - */ - regalloc(&fxc0, f, Z); - regalloc(&fxc2, f, Z); - regsalloc(&fxrat, &fconstnode); /* should be type float */ - gins(AMOVW, nodconst(0x43300000L), &fxc0); - gins(AMOVW, f, &fxc2); - gins(AMOVW, &fxc0, &fxrat); - gins(AXOR, nodconst(0x80000000L), &fxc2); - fxc1 = fxrat; - fxc1.type = nodrat->type; - fxc1.etype = nodrat->etype; - fxc1.xoffset += SZ_LONG; - gins(AMOVW, &fxc2, &fxc1); - regfree(&fxc2); - regfree(&fxc0); - regalloc(&nod, t, t); /* should be type float */ - gins(AFMOVD, &fxrat, &nod); - nodreg(&fxc1, t, NREG+FREGCVI); - gins(AFSUB, &fxc1, &nod); - a = AFMOVD; - if(tt == TFLOAT) - a = AFRSP; - gins(a, &nod, t); - regfree(&nod); - if(ft == TULONG) { - regalloc(&nod, t, Z); - if(tt == TFLOAT) { - gins(AFCMPU, t, Z); - p->to.type = D_FREG; - p->to.reg = FREGZERO; - gins(ABGE, Z, Z); - p1 = p; - gins(AFMOVS, nodfconst(4294967296.), &nod); - gins(AFADDS, &nod, t); - } else { - gins(AFCMPU, t, Z); - p->to.type = D_FREG; - p->to.reg = FREGZERO; - gins(ABGE, Z, Z); - p1 = p; - gins(AFMOVD, nodfconst(4294967296.), &nod); - gins(AFADD, &nod, t); - } - patch(p1, pc); - regfree(&nod); - } + fixtofloat(f, t); return; case TINT: case TUINT: diff -Nru /n/sources/plan9/sys/src/cmd/vc/cgen.c /sys/src/cmd/vc/cgen.c --- /n/sources/plan9/sys/src/cmd/vc/cgen.c Fri Mar 24 23:11:01 2006 +++ /sys/src/cmd/vc/cgen.c Mon Dec 14 00:00:00 2015 @@ -1,5 +1,7 @@ #include "gc.h" +static void genasop(int, Node*, Node*, Node*); + void cgen(Node *n, Node *nn) { @@ -216,6 +218,8 @@ regfree(&nod2); break; } + genasop(o, l, r, nn); + break; case OASLMUL: case OASLDIV: @@ -225,32 +229,7 @@ case OASMOD: if(l->op == OBIT) goto asbitop; - if(l->complex >= r->complex) { - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - regalloc(&nod1, r, Z); - cgen(r, &nod1); - } else { - regalloc(&nod1, r, Z); - cgen(r, &nod1); - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - } - - regalloc(&nod, n, nn); - gmove(&nod2, &nod); - gopcode(o, &nod1, Z, &nod); - gmove(&nod, &nod2); - if(nn != Z) - gopcode(OAS, &nod, Z, nn); - regfree(&nod); - regfree(&nod1); - if(l->addable < INDEXED) - regfree(&nod2); + genasop(o, l, r, nn); break; asbitop: @@ -521,6 +500,43 @@ cursafe = curs; } +static void +genasop(int o, Node *l, Node *r, Node *nn) +{ + Node nod, nod1, nod2; + int hardleft; + + hardleft = l->addable < INDEXED || l->complex >= FNX; + if(l->complex >= r->complex) { + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + regalloc(&nod1, r, Z); + cgen(r, &nod1); + } else { + regalloc(&nod1, r, Z); + cgen(r, &nod1); + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + } + if(nod1.type == nod2.type || !typefd[nod1.type->etype]) + regalloc(&nod, &nod2, nn); + else + regalloc(&nod, &nod1, Z); + gmove(&nod2, &nod); + gopcode(o, &nod1, Z, &nod); + gmove(&nod, &nod2); + if(nn != Z) + gmove(&nod2, nn); + regfree(&nod); + regfree(&nod1); + if(hardleft) + regfree(&nod2); +} + void reglcgen(Node *t, Node *n, Node *nn) { @@ -930,12 +946,12 @@ case OSTRUCT: /* - * rewrite so lhs has no fn call + * rewrite so lhs has no side effects */ - if(nn != Z && nn->complex >= FNX) { + if(nn != Z && side(nn)) { nod1 = *n; nod1.type = typ(TIND, n->type); - regret(&nod2, &nod1); + regalloc(&nod2, &nod1, Z); lcgen(nn, &nod2); regsalloc(&nod0, &nod1); gopcode(OAS, &nod2, Z, &nod0); diff -Nru /n/sources/plan9/sys/src/cmd/vc/gc.h /sys/src/cmd/vc/gc.h --- /n/sources/plan9/sys/src/cmd/vc/gc.h Thu Jun 13 22:29:26 2013 +++ /sys/src/cmd/vc/gc.h Mon Dec 14 00:00:00 2015 @@ -120,7 +120,7 @@ }; #define R ((Reg*)0) -#define NRGN 1000 /* was 600; raised for paranoia.c */ +#define NRGN 1000 struct Rgn { Reg* enter;