diff options
| author | Charles Forsyth <charles.forsyth@gmail.com> | 2015-07-20 21:30:52 +0100 |
|---|---|---|
| committer | Charles Forsyth <charles.forsyth@gmail.com> | 2015-07-20 21:30:52 +0100 |
| commit | 1414757b61ed827fd665afd74aa85bcd56541e80 (patch) | |
| tree | 0e06203a646473193b1031f02c91d983854714b9 | |
| parent | 3b7892b7446692609571d11dd832a80d59e2f539 (diff) | |
1. give name to SOFTFP option; 2. allow rotate to generate constant indices; 3. avoid add $0; 4. correct ordering of bounds check code; 5. distinguish nil reference from bounds error
| -rw-r--r-- | libinterp/comp-arm.c | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/libinterp/comp-arm.c b/libinterp/comp-arm.c index d2b1fc69..a3b1024e 100644 --- a/libinterp/comp-arm.c +++ b/libinterp/comp-arm.c @@ -11,6 +11,7 @@ */ #define RESCHED 1 /* check for interpreter reschedule */ +#define SOFTFP 1 enum { @@ -117,6 +118,8 @@ enum Blo = 0, /* offset of low order word in big */ Bhi = 4, /* offset of high order word in big */ + Lg2Rune = 2, + NCON = (0xFFC-8)/4, SRCOP = (1<<0), @@ -217,16 +220,19 @@ enum #define PATCH(ptr) *ptr |= (((ulong)code-(ulong)(ptr)-8)>>2) & 0x00ffffff #define MOV(src, dst) DP(AL, Mov, 0, dst, 0, src) + +#define FITS12(v) ((ulong)(v)<BITS(12)) #define FITS8(v) ((ulong)(v)<BITS(8)) #define FITS5(v) ((ulong)(v)<BITS(5)) /* assumes H==-1 */ #define CMPH(C, r) CMNI(C, r, 0, 0, 1) -#define NOTNIL(r) (CMPH(AL, (r)), CCALL(EQ, bounds)) +#define NOTNIL(r) (CMPH(AL, (r)), CCALL(EQ, nullity)) /* array bounds checking */ #define BCK(r, rb) (CMP(AL, rb, 0, 0, r), CCALL(LS, bounds)) #define BCKI(i, rb) (CMPI(AL, rb, 0, 0, i), CCALL(LS, bounds)) +#define BCKR(i, rb) (CMPI(AL, rb, 0, 0, 0)|(i), CCALL(LS, bounds)) static ulong* code; static ulong* base; @@ -467,7 +473,8 @@ memc(int c, int inst, ulong disp, int rm, int r) if(inst == Lea) { if(disp < BITS(8)) { - DPI(c, Add, rm, r, 0, disp); + if(disp != 0 || rm != r) + DPI(c, Add, rm, r, 0, disp); return; } if(-disp < BITS(8)) { @@ -688,6 +695,13 @@ bounds(void) } static void +nullity(void) +{ + /* mem(Stw, O(REG,FP), RREG, RFP); */ + error(exNilref); +} + +static void punt(Inst *i, int m, void (*fn)(void)) { ulong pc; @@ -903,7 +917,7 @@ cbraf(Inst *i, int r) { if(RESCHED) schedcheck(i); - if(0){ + if(!SOFTFP){ ulong *s=code; opflld(i, Ldf, FA4); midfl(i, Ldf, FA2); @@ -1257,7 +1271,7 @@ comp(Inst *i) comgoto(i); break; case IMOVF: - if(0){ + if(!SOFTFP){ opflld(i, Ldf, FA2); opflst(i, Stf, FA2); break; @@ -1275,7 +1289,8 @@ comp(Inst *i) case IHEADM: opwld(i, Ldw, RA1); NOTNIL(RA1); - DPI(AL, Add, RA1, RA1, 0, OA(List,data)); + if(OA(List,data) != 0) + DPI(AL, Add, RA1, RA1, 0, OA(List,data)); movmem(i); break; /* @@ -1548,33 +1563,31 @@ comp(Inst *i) opwld(i, Ldw, RA1); // RA1 = string NOTNIL(RA1); imm = 1; - if((i->add&ARM) != AXIMM || !FITS8((short)i->reg<<1)){ + if((i->add&ARM) != AXIMM || !FITS12((short)i->reg<<Lg2Rune) || immrot((short)i->reg) == 0){ mid(i, Ldw, RA2); // RA2 = i imm = 0; } mem(Ldw, O(String,len),RA1, RA0); // len<0 => index Runes, otherwise bytes + if(bflag){ + DPI(AL, Orr, RA0, RA3, 0, 0); + DPI(LT, Rsb, RA3, RA3, 0, 0); + if(imm) + BCKR(immrot((short)i->reg), RA3); + else + BCK(RA2, RA3); + } DPI(AL, Add, RA1, RA1, 0, O(String,data)); CMPI(AL, RA0, 0, 0, 0); - if(bflag) - DPI(LT, Rsb, RA0, RA0, 0, 0); if(imm){ LDB(GE, RA1, RA3, i->reg); - LDH(LT, RA1, RA3, (short)i->reg<<1); - if(bflag) - BCKI(i->reg, RA0); + LDW(LT, RA1, RA3, (short)i->reg<<Lg2Rune); } else { LDRB(GE, RA1, RA3, 0, RA2); - if(sizeof(Rune) == 4){ - DP(LT, Mov, 0, RA2, (2<<3), RA2); - LDRW(LT, RA1, RA3, 0, RA2); - }else{ - DP(LT, Mov, 0, RA2, (1<<3), RA2); - LDRH(LT, RA1, RA3, RA2); - } - if(bflag) - BCK(RA2, RA0); + DP(LT, Mov, 0, RA2, (Lg2Rune<<3), RA2); + LDRW(LT, RA1, RA3, 0, RA2); } opwst(i, Stw, RA3); +//if(pass){print("%D\n", i); das(s, code-s);} break; case IINDL: case IINDF: @@ -1582,9 +1595,9 @@ comp(Inst *i) case IINDB: opwld(i, Ldw, RA0); /* a */ NOTNIL(RA0); - mem(Ldw, O(Array, data), RA0, RA0); if(bflag) mem(Ldw, O(Array, len), RA0, RA2); + mem(Ldw, O(Array, data), RA0, RA0); r = 0; switch(i->op) { case IINDL: @@ -1595,10 +1608,11 @@ comp(Inst *i) r = 2; break; } - if(UXDST(i->add) == DST(AIMM) && FITS8(i->d.imm<<r)) { + if(UXDST(i->add) == DST(AIMM) && (imm = immrot(i->d.imm)) != 0) { if(bflag) - BCKI(i->d.imm, RA2); - DPI(AL, Add, RA0, RA0, 0, (i->d.imm<<r)); + BCKR(imm, RA2); + if(i->d.imm != 0) + DPI(AL, Add, RA0, RA0, 0, 0) | immrot(i->d.imm<<r); } else { opwst(i, Ldw, RA1); if(bflag) @@ -1606,6 +1620,7 @@ comp(Inst *i) DP(AL, Add, RA0, RA0, r<<3, RA1); } mid(i, Stw, RA0); +//if(pass){print("%D\n", i); das(s, code-s);} break; case IINDX: opwld(i, Ldw, RA0); /* a */ @@ -1622,6 +1637,7 @@ comp(Inst *i) MUL(AL, RA2, RA1, RA1); DP(AL, Add, RA1, RA0, 0, RA0); mid(i, Stw, RA0); +//if(pass){print("%D\n", i); das(s, code-s);} break; case IADDL: larith(i, Add, Adc); @@ -1684,8 +1700,9 @@ comp(Inst *i) case IADDF: r = Adf; arithf: - if(1){ + if(SOFTFP){ /* software fp */ + USED(r); punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); break; } @@ -1695,7 +1712,7 @@ comp(Inst *i) opflst(i, Stf, FA4); break; case INEGF: - if(1){ + if(SOFTFP){ punt(i, SRCOP|DSTOP, optab[i->op]); break; } @@ -1705,7 +1722,7 @@ comp(Inst *i) //if(pass){print("%D\n", i); das(s, code-s);} break; case ICVTWF: - if(1){ + if(SOFTFP){ punt(i, SRCOP|DSTOP, optab[i->op]); break; } @@ -1715,7 +1732,7 @@ comp(Inst *i) //if(pass){print("%D\n", i); das(s, code-s);} break; case ICVTFW: - if(1){ + if(SOFTFP){ punt(i, SRCOP|DSTOP, optab[i->op]); break; } |
