diff options
Diffstat (limited to 'src/cmd/8l/span.c')
-rw-r--r-- | src/cmd/8l/span.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/src/cmd/8l/span.c b/src/cmd/8l/span.c index 184a37d31..7745c361c 100644 --- a/src/cmd/8l/span.c +++ b/src/cmd/8l/span.c @@ -72,8 +72,9 @@ start: if(debug['v']) Bprint(&bso, "%5.2f span %d\n", cputime(), n); Bflush(&bso); - if(n > 50) { - print("span must be looping\n"); + if(n > 500) { + // TODO(rsc): figure out why nacl takes so long to converge. + print("span must be looping - %d\n", textsize); errorexit(); } c = INITTEXT; @@ -1045,6 +1046,12 @@ found: case Z_ib: v = vaddr(&p->to); case Zib_: + if(HEADTYPE == 8 && p->as == AINT && v == 3) { + // native client disallows all INT instructions. + // translate INT $3 to HLT. + *andptr++ = 0xf4; + break; + } *andptr++ = op; *andptr++ = v; break; @@ -1194,6 +1201,15 @@ found: } break; + case Zjmpcon: + v = p->to.offset - p->pc - 5; + *andptr++ = o->op[z+1]; + *andptr++ = v; + *andptr++ = v>>8; + *andptr++ = v>>16; + *andptr++ = v>>24; + break; + case Zloop: q = p->pcond; if(q) { @@ -1371,6 +1387,7 @@ asmins(Prog *p) { if(HEADTYPE == 8) { ulong npc; + static Prog *prefix; // native client // - pad indirect jump targets (aka ATEXT) to 32-byte boundary @@ -1386,15 +1403,27 @@ asmins(Prog *p) npc = p->pc + (andptr - and); p->pc += 31 & -npc; } + if(p->as == AREP || p->as == AREPN) { + // save prefix for next instruction, + // so that inserted NOPs do not split (e.g.) REP / MOVSL sequence. + prefix = p; + andptr = and; + return; + } andptr = and; + if(prefix) + doasm(prefix); doasm(p); npc = p->pc + (andptr - and); - if((p->pc&~31) != ((npc-1)&~31)) { + if(andptr > and && (p->pc&~31) != ((npc-1)&~31)) { // crossed 32-byte boundary; pad to boundary and try again p->pc += 31 & -p->pc; andptr = and; + if(prefix) + doasm(prefix); doasm(p); } + prefix = nil; } else { andptr = and; doasm(p); |