void
asmb(void)
{
- Prog *p;
int32 t;
int a, dynsym;
uint32 va, fo, w, symo, startva;
uint32 symdatva = SYMDATVA;
int strtabsize;
- Optab *o;
ElfEhdr *eh;
ElfPhdr *ph, *pph;
ElfShdr *sh;
OFFSET = HEADR;
seek(cout, OFFSET, 0);
pc = INITTEXT;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- for(p = cursym->text; p != P; p = p->link) {
- setarch(p);
- if(p->as == ATEXT)
- autosize = p->to.offset + 4;
- if(p->pc != pc) {
- diag("phase error %ux sb %ux",
- p->pc, pc);
- if(!debug['a'])
- prasm(curp);
- pc = p->pc;
- }
- curp = p;
- o = oplook(p); /* could probably avoid this call */
- if(thumb)
- thumbasmout(p, o);
- else
- asmout(p, o);
- pc += o->size;
- }
- }
- cflush();
+ codeblk(pc, segtext.sect->len);
+ pc += segtext.sect->len;
if(seek(cout, 0, 1) != pc - segtext.vaddr + segtext.fileoff)
diag("text phase error");
}
void
-asmout(Prog *p, Optab *o)
+asmout(Prog *p, Optab *o, int32 *out)
{
int32 o1, o2, o3, o4, o5, o6, v;
int r, rf, rt, rt2;
+ Reloc *rel;
PP = p;
o1 = 0;
case 11: /* word */
aclass(&p->to);
o1 = instoffset;
+ if(p->to.sym != S) {
+ rel = addrel(cursym);
+ rel->off = pc - cursym->value;
+ rel->siz = 4;
+ rel->type = D_ADDR;
+ rel->sym = p->to.sym;
+ rel->add = p->to.offset;
+ o1 = 0;
+ }
break;
case 12: /* movw $lcon, reg */
o1 |= (p->scond & C_SCOND) << 28;
break;
}
+
+ out[0] = o1;
+ out[1] = o2;
+ out[2] = o3;
+ out[3] = o4;
+ out[4] = o5;
+ out[5] = o6;
+ return;
v = p->pc;
switch(o->size) {
{
Prog *p, *op;
Optab *o;
- int m, bflag;
- int32 c, otxt;
+ int m, bflag, i, v;
+ int32 c, otxt, out[6];
int lastthumb = -1;
Section *rosect, *sect;
Sym *sym;
+ uchar *bp;
if(debug['v'])
Bprint(&bso, "%5.2f span\n", cputime());
p = cursym->text;
setarch(p);
p->pc = c;
+ cursym->value = c;
- if(blitrl && lastthumb != -1 && lastthumb != thumb){ // flush literal pool
- if(flushpool(op, 0, 1))
- c = p->pc = scan(op, p, c);
- }
lastthumb = thumb;
autosize = p->to.offset + 4;
if(p->from.sym != S)
c = p->pc = scan(op, p, c);
}
if(m == 0) {
- if(p->as == ATEXT) {
- }
diag("zero-width instruction\n%P", p);
continue;
}
flushpool(p, 0, 0);
c += m;
}
- if(blitrl && cursym->next == nil){
+ if(blitrl){
if(thumb && isbranch(op))
pool.extra += brextra(op);
if(checkpool(op, 0))
c = scan(op, P, c);
}
+ cursym->size = c - cursym->value;
}
/*
bflag = 0;
c = INITTEXT;
for(cursym = textp; cursym != nil; cursym = cursym->next) {
+ cursym->value = c;
for(p = cursym->text; p != P; p = p->link) {
setarch(p);
p->pc = c;
}
c += m;
}
+ cursym->size = c - cursym->value;
}
}
oop = op = nil;
again = 0;
for(cursym = textp; cursym != nil; cursym = cursym->next) {
+ cursym->value = c;
for(p = cursym->text; p != P; oop = op, op = p, p = p->link) {
setarch(p);
if(p->pc != c)
}
c += m;
}
+ cursym->size = c - cursym->value;
}
if(c != lastc || again){
lastc = c;
}
}
c = rnd(c, 8);
-
xdefine("etext", STEXT, c);
- for(cursym = textp; cursym != nil; cursym = cursym->next)
- cursym->value = cursym->text->pc;
textsize = c - INITTEXT;
+ /*
+ * lay out the code. all the pc-relative code references,
+ * even cross-function, are resolved now;
+ * only data references need to be relocated.
+ * with more work we could leave cross-function
+ * code references to be relocated too, and then
+ * perhaps we'd be able to parallelize the span loop above.
+ */
+ for(cursym = textp; cursym != nil; cursym = cursym->next) {
+ p = cursym->text;
+ setarch(p);
+ autosize = p->to.offset + 4;
+ symgrow(cursym, cursym->size);
+
+ bp = cursym->p;
+ for(p = p->link; p != P; p = p->link) {
+ pc = p->pc;
+ curp = p;
+ o = oplook(p);
+ asmout(p, o, out);
+ for(i=0; i<o->size/4; i++) {
+ v = out[i];
+ *bp++ = v;
+ *bp++ = v>>8;
+ *bp++ = v>>16;
+ *bp++ = v>>24;
+ }
+ }
+ }
+
rosect = segtext.sect->next;
if(rosect) {
if(INITRND)