summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/ql/asm.c104
-rw-r--r--utils/ql/asmout.c77
-rw-r--r--utils/ql/l.h6
-rw-r--r--utils/ql/obj.c53
-rw-r--r--utils/ql/optab.c19
-rw-r--r--utils/ql/span.c37
6 files changed, 219 insertions, 77 deletions
diff --git a/utils/ql/asm.c b/utils/ql/asm.c
index 25d4c772..be1a57a1 100644
--- a/utils/ql/asm.c
+++ b/utils/ql/asm.c
@@ -1,6 +1,7 @@
#include "l.h"
#define KMASK 0xF0000000
+#define JMPSZ sizeof(u32int) /* size of bootstrap jump section */
#define LPUT(c)\
{\
@@ -50,12 +51,15 @@ asmb(void)
Prog *p;
long t;
Optab *o;
+ long prevpc;
if(debug['v'])
Bprint(&bso, "%5.2f asm\n", cputime());
Bflush(&bso);
+
+ /* emit text segment */
seek(cout, HEADR, 0);
- pc = INITTEXT;
+ prevpc = pc = INITTEXT;
for(p = firstp; p != P; p = p->link) {
if(p->as == ATEXT) {
curtext = p;
@@ -79,14 +83,32 @@ asmb(void)
pc += 4;
}
pc += o->size;
+ if (prevpc & (1<<31) && (pc & (1<<31)) == 0) {
+ char *tn;
+
+ tn = "?none?";
+ if(curtext != P && curtext->from.sym != S)
+ tn = curtext->from.sym->name;
+ Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn);
+ }
+ prevpc = pc;
}
+ /* for virtex 4, inject a jmp instruction after other text */
+ if(HEADTYPE == 6)
+ /* branch to absolute entry address (0xfffe2100) */
+ lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2);
+
if(debug['a'])
Bprint(&bso, "\n");
Bflush(&bso);
cflush();
+ /* emit data segment */
curtext = P;
switch(HEADTYPE) {
+ case 6:
+ textsize += JMPSZ;
+ /* fall through */
case 0:
case 1:
case 2:
@@ -126,6 +148,7 @@ asmb(void)
case 1:
case 2:
case 5:
+ case 6:
seek(cout, HEADR+textsize+datsize, 0);
break;
case 3:
@@ -154,6 +177,7 @@ asmb(void)
cflush();
}
+ /* back up and write the header */
seek(cout, 0L, 0);
switch(HEADTYPE) {
case 0:
@@ -290,6 +314,10 @@ asmb(void)
lput(0x80L); /* flags */
break;
case 5:
+ /*
+ * customised for blue/gene,
+ * notably the alignment and KMASK masking.
+ */
strnput("\177ELF", 4); /* e_ident */
CPUT(1); /* class = 32 bit */
CPUT(2); /* data = MSB */
@@ -335,8 +363,8 @@ asmb(void)
lput(0L); /* data - type = PT_NULL */
lput(HEADR+textsize+datsize); /* file offset */
- lput(0L);
- lput(0L);
+ lput(0L); /* vaddr */
+ lput(0L); /* paddr */
lput(symsize); /* symbol table size */
lput(lcsize); /* line number size */
lput(0x04L); /* protections = R */
@@ -392,6 +420,76 @@ asmb(void)
cput(0);
break;
+ case 6:
+ /*
+ * customised for virtex 4 boot,
+ * notably the alignment and KMASK masking.
+ */
+ strnput("\177ELF", 4); /* e_ident */
+ CPUT(1); /* class = 32 bit */
+ CPUT(2); /* data = MSB */
+ CPUT(1); /* version = CURRENT */
+ strnput("", 9);
+ lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */
+ lput(1L); /* version = CURRENT */
+ lput(entryvalue()); /* entry vaddr */
+ lput(52L); /* offset to first phdr */
+
+ debug['S'] = 1; /* no symbol table */
+ if(debug['S']){
+ lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */
+ lput(0L); /* flags = PPC */
+ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
+ lput((4L<<16)|40L); /* # Phdrs & Shdr size */
+ lput((4L<<16)|2L); /* # Shdrs & shdr string size */
+ }
+ else{
+ lput(0L);
+ lput(0L); /* flags = PPC */
+ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
+ lput((4L<<16)|0L); /* # Phdrs & Shdr size */
+ lput((4L<<16)|0L); /* # Shdrs & shdr string size */
+ }
+
+ lput(1L); /* text - type = PT_LOAD */
+ lput(HEADR); /* file offset */
+ lput(INITTEXT); /* vaddr */
+ lput(INITTEXT); /* paddr */
+ lput(textsize-JMPSZ); /* file size */
+ lput(textsize-JMPSZ); /* memory size */
+ lput(0x05L); /* protections = RX */
+ lput(0); /* alignment */
+
+ lput(1L); /* data - type = PT_LOAD */
+ lput(HEADR+textsize); /* file offset */
+ lput(INITDAT); /* vaddr */
+ lput(INITDAT); /* paddr */
+ lput(datsize); /* file size */
+ lput(datsize+bsssize); /* memory size */
+ lput(0x07L); /* protections = RWX */
+ lput(0); /* alignment */
+
+ lput(0L); /* data - type = PT_NULL */
+ lput(HEADR+textsize+datsize); /* file offset */
+ lput(0L); /* vaddr */
+ lput(0L); /* paddr */
+ lput(symsize); /* symbol table size */
+ lput(lcsize); /* line number size */
+ lput(0x04L); /* protections = R */
+ lput(0x04L); /* alignment code?? */
+
+ /* add tiny text section at end with jmp to start */
+ lput(1L); /* text - type = PT_LOAD */
+ lput(HEADR+textsize-JMPSZ); /* file offset */
+ lput(0xFFFFFFFC); /* vaddr */
+ lput(0xFFFFFFFC); /* paddr */
+ lput(JMPSZ); /* file size */
+ lput(JMPSZ); /* memory size */
+ lput(0x05L); /* protections = RX */
+ lput(0); /* disable alignment */
+
+ cflush();
+ break;
}
cflush();
}
diff --git a/utils/ql/asmout.c b/utils/ql/asmout.c
index 96cb3df3..4e685a9c 100644
--- a/utils/ql/asmout.c
+++ b/utils/ql/asmout.c
@@ -672,16 +672,24 @@ asmout(Prog *p, Optab *o, int aflag)
if(p->from.type == D_REG) {
r = p->from.reg;
v = p->to.offset;
- if(p->to.type == D_DCR)
- o1 = OPVCC(31,451,0,0); /* mtdcr */
- else
+ if(p->to.type == D_DCR) {
+ if(p->to.reg != NREG) {
+ o1 = OPVCC(31,387,0,0); /* mtdcrx */
+ v = p->to.reg;
+ }else
+ o1 = OPVCC(31,451,0,0); /* mtdcr */
+ }else
o1 = OPVCC(31,467,0,0); /* mtspr */
} else {
r = p->to.reg;
v = p->from.offset;
- if(p->from.type == D_DCR)
- o1 = OPVCC(31,323,0,0); /* mfdcr */
- else
+ if(p->from.type == D_DCR) {
+ if(p->from.reg != NREG) {
+ o1 = OPVCC(31,259,0,0); /* mfdcrx */
+ v = p->from.reg;
+ }else
+ o1 = OPVCC(31,323,0,0); /* mfdcr */
+ }else
o1 = OPVCC(31,339,0,0); /* mfspr */
}
o1 = AOP_RRR(o1, r, 0, 0) | ((v&0x1f)<<16) | (((v>>5)&0x1f)<<11);
@@ -984,25 +992,22 @@ oprrr(int a)
case AFXNMSUB: return OPVCC(0,29,0,0);
case AFXCPNMSUB: return OPVCC(0,30,0,0);
case AFXCSNMSUB: return OPVCC(0,31,0,0);
- case AFMOVPD: return OPVCC(0,32,0,0); /* fpmr, X form */
case AFPABS: return OPVCC(0,96,0,0);
case AFPNEG: return OPVCC(0,160,0,0);
case AFPRSP: return OPVCC(0,192,0,0);
case AFPNABS: return OPVCC(0,224,0,0);
- case AFMOVSD: return OPVCC(0,288,0,0); /* fsmr */
case AFSCMP: return OPVCC(0,320,0,0)|(3<<21);
case AFSABS: return OPVCC(0,352,0,0);
case AFSNEG: return OPVCC(0,416,0,0);
case AFSNABS: return OPVCC(0,480,0,0);
- case AFMOVXD: return OPVCC(0,544,0,0);
case AFPCTIW: return OPVCC(0,576,0,0);
case AFPCTIWZ: return OPVCC(0,704,0,0);
case AFPMOVD: return OPVCC(0,32,0,0); /* fpmr */
case AFSMOVD: return OPVCC(0,288,0,0); /* fsmr */
case AFXMOVD: return OPVCC(0,544,0,0); /* fxmr */
- case AFSMOVP: return OPVCC(0,800,0,0); /* fsmtp */
- case AFPMOVS: return OPVCC(0,928,0,0); /* fsmfp */
+ case AFMOVSPD: return OPVCC(0,800,0,0); /* fsmtp */
+ case AFMOVPSD: return OPVCC(0,928,0,0); /* fsmfp */
case AFXCPNPMA: return OPVCC(4,24,0,0);
case AFXCSNPMA: return OPVCC(4,25,0,0);
@@ -1290,18 +1295,18 @@ oploadx(int a)
case AECIWX: return OPVCC(31,310,0,0); /* eciwx */
case ALWAR: return OPVCC(31,20,0,0); /* lwarx */
case ALSW: return OPVCC(31,533,0,0); /* lswx */
- case AFMOVSS: return OPVCC(31,142,0,0); /* lfssx */
- case AFMOVSSU: return OPVCC(31,174,0,0); /* lfssux */
- case AFMOVSD: return OPVCC(31,206,0,0);
- case AFMOVSDU: return OPVCC(31,238,0,0);
- case AFMOVXS: return OPVCC(31,270,0,0);
- case AFMOVSXU: return OPVCC(31,302,0,0);
- case AFMOVXD: return OPVCC(31,334,0,0);
- case AFMOVXDU: return OPVCC(31,366,0,0);
- case AFMOVPS: return OPVCC(31,398,0,0);
- case AFMOVPSU: return OPVCC(31,430,0,0);
- case AFMOVPD: return OPVCC(31,462,0,0);
- case AFMOVPDU: return OPVCC(31,494,0,0);
+ case AFSMOVS: return OPVCC(31,142,0,0); /* lfssx */
+ case AFSMOVSU: return OPVCC(31,174,0,0); /* lfssux */
+ case AFSMOVD: return OPVCC(31,206,0,0); /* lfsdx */
+ case AFSMOVDU: return OPVCC(31,238,0,0); /* lfsdux */
+ case AFXMOVS: return OPVCC(31,270,0,0); /* lfxsx */
+ case AFXMOVSU: return OPVCC(31,302,0,0); /* lfxsux */
+ case AFXMOVD: return OPVCC(31,334,0,0); /* lfxdx */
+ case AFXMOVDU: return OPVCC(31,366,0,0); /* lfxdux */
+ case AFPMOVS: return OPVCC(31,398,0,0); /* lfpsx */
+ case AFPMOVSU: return OPVCC(31,430,0,0); /* lfpsux */
+ case AFPMOVD: return OPVCC(31,462,0,0); /* lfpdx */
+ case AFPMOVDU: return OPVCC(31,494,0,0); /* lfpdux */
}
diag("bad loadx opcode %A", a);
return 0;
@@ -1361,19 +1366,19 @@ opstorex(int a)
case AMOVWBR: return OPVCC(31,662,0,0); /* stwbrx */
case ASTWCCC: return OPVCC(31,150,0,1); /* stwcx. */
case AECOWX: return OPVCC(31,438,0,0); /* ecowx */
- case AFMOVSS: return OPVCC(31,654,0,0);
-/* case AFMOVSSU: return OPVCC(31,yy,0,0); */ /* stfssux not known */
-/* case AFMOVSD: return OPVCC(31,yy,0,0); */ /* stfsdx not known */
- case AFMOVSDU: return OPVCC(31,750,0,0);
- case AFMOVXS: return OPVCC(31,782,0,0);
- case AFMOVSXU: return OPVCC(31,814,0,0);
- case AFMOVXD: return OPVCC(31,846,0,0);
- case AFMOVXDU: return OPVCC(31,878,0,0);
- case AFMOVPS: return OPVCC(31,910,0,0);
- case AFMOVPSU: return OPVCC(31,942,0,0);
- case AFMOVPD: return OPVCC(31,974,0,0);
- case AFMOVPDU: return OPVCC(31,1006,0,0);
- case AFMOVPIW: return OPVCC(31,526,0,0); /* stfpiwx */
+ case AFSMOVS: return OPVCC(31,654,0,0); /* stfssx */
+/* case AFSMOVSU: return OPVCC(31,yy,0,0); */ /* stfssux not known */
+/* case AFSMOVD: return OPVCC(31,yy,0,0); */ /* stfsdx not known */
+ case AFSMOVDU: return OPVCC(31,750,0,0); /* stfsdux */
+ case AFXMOVS: return OPVCC(31,782,0,0); /* stfxsx */
+ case AFXMOVSU: return OPVCC(31,814,0,0); /* stfxsux */
+ case AFXMOVD: return OPVCC(31,846,0,0); /* stfxdx */
+ case AFXMOVDU: return OPVCC(31,878,0,0); /* stfxdux */
+ case AFPMOVS: return OPVCC(31,910,0,0); /* stfpsx */
+ case AFPMOVSU: return OPVCC(31,942,0,0); /* stfpsux */
+ case AFPMOVD: return OPVCC(31,974,0,0); /* stfpdx */
+ case AFPMOVDU: return OPVCC(31,1006,0,0); /* stfpdux */
+ case AFPMOVIW: return OPVCC(31,526,0,0); /* stfpiwx */
}
diag("unknown storex opcode %A", a);
return 0;
diff --git a/utils/ql/l.h b/utils/ql/l.h
index 34cb742f..4ef775c0 100644
--- a/utils/ql/l.h
+++ b/utils/ql/l.h
@@ -303,6 +303,7 @@ void* mysbrk(ulong);
void names(void);
void nocache(Prog*);
void noops(void);
+void nopout(Prog*);
void nuxiinit(void);
void objfile(char*);
int ocmp(void*, void*);
@@ -327,9 +328,12 @@ void xdefine(char*, int, long);
void xfol(Prog*);
void zerosig(char*);
+#pragma varargck type "A" int
+#pragma varargck type "A" uint
#pragma varargck type "D" Adr*
#pragma varargck type "N" Adr*
#pragma varargck type "P" Prog*
#pragma varargck type "R" int
-#pragma varargck type "A" int
#pragma varargck type "S" char*
+
+#pragma varargck argpos diag 1
diff --git a/utils/ql/obj.c b/utils/ql/obj.c
index adff8dfd..8026a0de 100644
--- a/utils/ql/obj.c
+++ b/utils/ql/obj.c
@@ -17,10 +17,13 @@ char *thestring = "power";
/*
* -H0 -T0x200000 -R0 is boot
* -H1 -T0x100000 -R4 is Be boot
- * -H2 -T4128 -R4096 is plan9 format
+ * -H2 -T0x100020 -R0x100000 is plan9 format (was -T4128 -R4096)
* -H3 -T0x02010000 -D0x00001000 is raw
* -H4 -T0x1000200 -D0x20000e00 -R4 is aix xcoff executable
* -H5 -T0x80010000 -t0x10000 ELF, phys = 10000, vaddr = 0x8001...
+ * appropriate for blue gene (bg/l anyway)
+ * -H6 -T0xfffe2100 -R4 ELF, phys = vaddr = 0xfffe2100
+ * appropriate for virtex 4 boot
*/
static int
@@ -150,11 +153,11 @@ main(int argc, char *argv[])
case 2: /* plan 9 */
HEADR = 32L;
if(INITTEXT == -1)
- INITTEXT = 4128;
+ INITTEXT = 0x100020;
if(INITDAT == -1)
INITDAT = 0;
if(INITRND == -1)
- INITRND = 4096;
+ INITRND = 0x100000;
break;
case 3: /* raw */
HEADR = 0;
@@ -177,6 +180,7 @@ main(int argc, char *argv[])
INITRND = 0;
break;
case 5: /* elf executable */
+ case 6: /* elf for virtex 4 */
HEADR = rnd(52L+3*32L, 16);
if(INITTEXT == -1)
INITTEXT = 0x00400000L+HEADR;
@@ -1220,16 +1224,24 @@ void
doprof2(void)
{
Sym *s2, *s4;
- Prog *p, *q, *ps2, *ps4;
+ Prog *p, *q, *q2, *ps2, *ps4;
if(debug['v'])
Bprint(&bso, "%5.2f profile 2\n", cputime());
Bflush(&bso);
- s2 = lookup("_profin", 0);
- s4 = lookup("_profout", 0);
+ if(debug['e']){
+ s2 = lookup("_tracein", 0);
+ s4 = lookup("_traceout", 0);
+ }else{
+ s2 = lookup("_profin", 0);
+ s4 = lookup("_profout", 0);
+ }
if(s2->type != STEXT || s4->type != STEXT) {
- diag("_profin/_profout not defined");
+ if(debug['e'])
+ diag("_tracein/_traceout not defined %d %d", s2->type, s4->type);
+ else
+ diag("_profin/_profout not defined");
return;
}
@@ -1270,7 +1282,20 @@ doprof2(void)
q->line = p->line;
q->pc = p->pc;
q->link = p->link;
- p->link = q;
+ if(debug['e']){ /* embedded tracing */
+ q2 = prg();
+ p->link = q2;
+ q2->link = q;
+
+ q2->line = p->line;
+ q2->pc = p->pc;
+
+ q2->as = ABR;
+ q2->to.type = D_BRANCH;
+ q2->to.sym = p->to.sym;
+ q2->cond = q->link;
+ }else
+ p->link = q;
p = q;
p->as = ABL;
p->to.type = D_BRANCH;
@@ -1280,7 +1305,17 @@ doprof2(void)
continue;
}
if(p->as == ARETURN) {
-
+ /*
+ * RETURN (default)
+ */
+ if(debug['e']){ /* embedded tracing */
+ q = prg();
+ q->line = p->line;
+ q->pc = p->pc;
+ q->link = p->link;
+ p->link = q;
+ p = q;
+ }
/*
* RETURN
*/
diff --git a/utils/ql/optab.c b/utils/ql/optab.c
index 57813f7f..4e44caf1 100644
--- a/utils/ql/optab.c
+++ b/utils/ql/optab.c
@@ -206,8 +206,6 @@ Optab optab[] =
{ AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 7, 4, REGZERO },
{ AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0 },
- { AFPMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0 },
-
{ ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0 },
{ AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0 },
@@ -287,13 +285,18 @@ Optab optab[] =
{ AMACCHW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0 }, /* op rb,ra,rt */
- { AFMOVSS, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0 },
- { AFMOVSS, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0 },
- { AFMOVSS, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0 },
- { AFMOVSS, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0 },
+ { AFSMOVS, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0 },
+ { AFSMOVS, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0 },
+ { AFSMOVS, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0 },
+ { AFSMOVS, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0 },
+
+ { AFPMOVD, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0 },
+ { AFPMOVD, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0 },
+ { AFPMOVD, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0 },
+ { AFPMOVD, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0 },
- { AFMOVPIW, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0 },
- { AFMOVPIW, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0 },
+ { AFPMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0 }, /* f[xps]mr */
+ { AFMOVSPD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0 }, /* fsm[tf]p */
{ AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0 },
};
diff --git a/utils/ql/span.c b/utils/ql/span.c
index 4a23f68f..cc4e5bb8 100644
--- a/utils/ql/span.c
+++ b/utils/ql/span.c
@@ -499,8 +499,6 @@ buildop(void)
case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
oprange[ASTWCCC] = oprange[r];
break;
- case AFMOVPIW: /* indexed floating store */
- break;
case AREM: /* macro */
oprange[AREMCC] = oprange[r];
oprange[AREMV] = oprange[r];
@@ -845,12 +843,6 @@ buildop(void)
oprange[AFMOVS] = oprange[r];
oprange[AFMOVSU] = oprange[r];
break;
- case AFPMOVD:
- oprange[AFSMOVD] = oprange[r];
- oprange[AFXMOVD] = oprange[r];
- oprange[AFSMOVP] = oprange[r];
- oprange[AFPMOVS] = oprange[r];
- break;
case AECIWX:
oprange[ALWAR] = oprange[r];
break;
@@ -861,18 +853,23 @@ buildop(void)
case AMOVHBR:
oprange[AMOVWBR] = oprange[r];
break;
- case AFMOVSS: /* indexed floating loads and stores (fp2) */
- oprange[AFMOVSSU] = oprange[r];
- oprange[AFMOVSD] = oprange[r];
- oprange[AFMOVSDU] = oprange[r];
- oprange[AFMOVXS] = oprange[r];
- oprange[AFMOVSXU] = oprange[r];
- oprange[AFMOVXD] = oprange[r];
- oprange[AFMOVXDU] = oprange[r];
- oprange[AFMOVPS] = oprange[r];
- oprange[AFMOVPSU] = oprange[r];
- oprange[AFMOVPD] = oprange[r];
- oprange[AFMOVPDU] = oprange[r];
+ case AFSMOVS: /* indexed floating loads and stores (fp2) */
+ oprange[AFSMOVSU] = oprange[r];
+ oprange[AFSMOVDU] = oprange[r];
+ oprange[AFXMOVS] = oprange[r];
+ oprange[AFXMOVSU] = oprange[r];
+ oprange[AFXMOVDU] = oprange[r];
+ oprange[AFPMOVS] = oprange[r];
+ oprange[AFPMOVSU] = oprange[r];
+ oprange[AFPMOVDU] = oprange[r];
+ oprange[AFPMOVIW] = oprange[r];
+ break;
+ case AFPMOVD: /* indexed load/store and moves (fp2) */
+ oprange[AFSMOVD] = oprange[r];
+ oprange[AFXMOVD] = oprange[r];
+ break;
+ case AFMOVSPD: /* move between fp reg sets (fp2) */
+ oprange[AFMOVPSD] = oprange[r];
break;
case AADD:
case AANDCC: /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */