From 647adfbc462388549008eda6af62f2e74b260d63 Mon Sep 17 00:00:00 2001 From: forsyth Date: Tue, 27 Apr 2010 13:33:26 +0100 Subject: 20100427-1333 --- utils/ql/asm.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- utils/ql/asmout.c | 77 +++++++++++++++++++++------------------- utils/ql/l.h | 6 +++- utils/ql/obj.c | 53 +++++++++++++++++++++++----- utils/ql/optab.c | 19 +++++----- utils/ql/span.c | 37 +++++++++---------- 6 files changed, 219 insertions(+), 77 deletions(-) (limited to 'utils') 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 */ @@ -391,6 +419,76 @@ asmb(void) cput(0); 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 */ -- cgit v1.2.3