mirror of https://github.com/golang/go.git
5l: delete dead code
Thumb code and ARM pre-V4 code is unused, unmaintained, and almost certainly wrong by now. Every time I try to change 5l I have to sort out what's dead code and what's not. 30% of lines of code in this directory deleted. R=ken2 CC=golang-dev https://golang.org/cl/4601049
This commit is contained in:
parent
2ac375b2df
commit
3e57d7f7bf
|
|
@ -53,8 +53,6 @@
|
||||||
#define REGLINK 14
|
#define REGLINK 14
|
||||||
#define REGPC 15
|
#define REGPC 15
|
||||||
|
|
||||||
#define REGTMPT 7 /* used by the loader for thumb code */
|
|
||||||
|
|
||||||
#define NFREG 8
|
#define NFREG 8
|
||||||
#define FREGRET 0
|
#define FREGRET 0
|
||||||
#define FREGEXT 7
|
#define FREGEXT 7
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ OFILES=\
|
||||||
optab.$O\
|
optab.$O\
|
||||||
pass.$O\
|
pass.$O\
|
||||||
prof.$O\
|
prof.$O\
|
||||||
thumb.$O\
|
|
||||||
softfloat.$O\
|
softfloat.$O\
|
||||||
span.$O\
|
span.$O\
|
||||||
symtab.$O\
|
symtab.$O\
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,6 @@ asmb(void)
|
||||||
// Bprint(&bso, "%5.2f dwarf\n", cputime());
|
// Bprint(&bso, "%5.2f dwarf\n", cputime());
|
||||||
// dwarfemitdebugsections();
|
// dwarfemitdebugsections();
|
||||||
}
|
}
|
||||||
asmthumbmap();
|
|
||||||
cflush();
|
cflush();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -728,59 +727,6 @@ nopstat(char *f, Count *c)
|
||||||
(double)(c->outof - c->count)/c->outof);
|
(double)(c->outof - c->count)/c->outof);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
outt(int32 f, int32 l)
|
|
||||||
{
|
|
||||||
if(debug['L'])
|
|
||||||
Bprint(&bso, "tmap: %ux-%ux\n", f, l);
|
|
||||||
lput(f);
|
|
||||||
lput(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
asmthumbmap(void)
|
|
||||||
{
|
|
||||||
int32 pc, lastt;
|
|
||||||
Prog *p;
|
|
||||||
|
|
||||||
if(!seenthumb)
|
|
||||||
return;
|
|
||||||
pc = 0;
|
|
||||||
lastt = -1;
|
|
||||||
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
|
||||||
p = cursym->text;
|
|
||||||
pc = p->pc - INITTEXT;
|
|
||||||
setarch(p);
|
|
||||||
if(thumb){
|
|
||||||
if(p->from.sym->foreign){ // 8 bytes of ARM first
|
|
||||||
if(lastt >= 0){
|
|
||||||
outt(lastt, pc-1);
|
|
||||||
lastt = -1;
|
|
||||||
}
|
|
||||||
pc += 8;
|
|
||||||
}
|
|
||||||
if(lastt < 0)
|
|
||||||
lastt = pc;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(p->from.sym->foreign){ // 4 bytes of THUMB first
|
|
||||||
if(lastt < 0)
|
|
||||||
lastt = pc;
|
|
||||||
pc += 4;
|
|
||||||
}
|
|
||||||
if(lastt >= 0){
|
|
||||||
outt(lastt, pc-1);
|
|
||||||
lastt = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(cursym->next == nil)
|
|
||||||
for(; p != P; p = p->link)
|
|
||||||
pc = p->pc = INITTEXT;
|
|
||||||
}
|
|
||||||
if(lastt >= 0)
|
|
||||||
outt(lastt, pc+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
asmout(Prog *p, Optab *o, int32 *out)
|
asmout(Prog *p, Optab *o, int32 *out)
|
||||||
{
|
{
|
||||||
|
|
@ -804,7 +750,7 @@ if(debug['P']) print("%ux: %P type %d\n", (uint32)(p->pc), p, o->type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0: /* pseudo ops */
|
case 0: /* pseudo ops */
|
||||||
if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->name, p->from.sym->thumb, p->from.sym->foreign, p->from.sym->fnptr);
|
if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p->from.sym->fnptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* op R,[R],R */
|
case 1: /* op R,[R],R */
|
||||||
|
|
@ -868,10 +814,6 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
|
||||||
v = -8;
|
v = -8;
|
||||||
if(p->cond != P)
|
if(p->cond != P)
|
||||||
v = (p->cond->pc - pc) - 8;
|
v = (p->cond->pc - pc) - 8;
|
||||||
#ifdef CALLEEBX
|
|
||||||
if(p->as == ABL)
|
|
||||||
v += fninc(p->to.sym);
|
|
||||||
#endif
|
|
||||||
o1 = opbra(p->as, p->scond);
|
o1 = opbra(p->as, p->scond);
|
||||||
o1 |= (v >> 2) & 0xffffff;
|
o1 |= (v >> 2) & 0xffffff;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1328,19 +1270,7 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
|
||||||
o2 ^= (1<<6);
|
o2 ^= (1<<6);
|
||||||
break;
|
break;
|
||||||
case 74: /* bx $I */
|
case 74: /* bx $I */
|
||||||
#ifdef CALLEEBX
|
diag("ABX $I");
|
||||||
diag("bx $i case (arm)");
|
|
||||||
#endif
|
|
||||||
if(!seenthumb)
|
|
||||||
diag("ABX $I and seenthumb==0");
|
|
||||||
v = p->cond->pc;
|
|
||||||
if(p->to.sym->thumb)
|
|
||||||
v |= 1; // T bit
|
|
||||||
o1 = olr(8, REGPC, REGTMP, p->scond&C_SCOND); // mov 8(PC), Rtmp
|
|
||||||
o2 = oprrr(AADD, p->scond) | immrot(8) | (REGPC<<16) | (REGLINK<<12); // add 8,PC, LR
|
|
||||||
o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // bx Rtmp
|
|
||||||
o4 = opbra(AB, 14); // B over o6
|
|
||||||
o5 = v;
|
|
||||||
break;
|
break;
|
||||||
case 75: /* bx O(R) */
|
case 75: /* bx O(R) */
|
||||||
aclass(&p->to);
|
aclass(&p->to);
|
||||||
|
|
@ -1359,14 +1289,7 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
|
||||||
o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // BX Rtmp
|
o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // BX Rtmp
|
||||||
break;
|
break;
|
||||||
case 76: /* bx O(R) when returning from fn*/
|
case 76: /* bx O(R) when returning from fn*/
|
||||||
if(!seenthumb)
|
diag("ABXRET");
|
||||||
diag("ABXRET and seenthumb==0");
|
|
||||||
aclass(&p->to);
|
|
||||||
// print("ARM BXRET %d(R%d)\n", instoffset, p->to.reg);
|
|
||||||
if(instoffset != 0)
|
|
||||||
diag("non-zero offset in ABXRET");
|
|
||||||
// o1 = olr(instoffset, p->to.reg, REGTMP, p->scond); // mov O(R), Rtmp
|
|
||||||
o1 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg; // BX R
|
|
||||||
break;
|
break;
|
||||||
case 77: /* ldrex oreg,reg */
|
case 77: /* ldrex oreg,reg */
|
||||||
aclass(&p->from);
|
aclass(&p->from);
|
||||||
|
|
|
||||||
|
|
@ -144,8 +144,6 @@ struct Sym
|
||||||
int32 sig;
|
int32 sig;
|
||||||
int32 size;
|
int32 size;
|
||||||
uchar special;
|
uchar special;
|
||||||
uchar thumb; // thumb code
|
|
||||||
uchar foreign; // called by arm if thumb, by thumb if arm
|
|
||||||
uchar fnptr; // used as fn ptr
|
uchar fnptr; // used as fn ptr
|
||||||
Sym* hash; // in hash table
|
Sym* hash; // in hash table
|
||||||
Sym* allsym; // in all symbol list
|
Sym* allsym; // in all symbol list
|
||||||
|
|
@ -208,7 +206,6 @@ enum
|
||||||
LFROM = 1<<0,
|
LFROM = 1<<0,
|
||||||
LTO = 1<<1,
|
LTO = 1<<1,
|
||||||
LPOOL = 1<<2,
|
LPOOL = 1<<2,
|
||||||
V4 = 1<<3, /* arm v4 arch */
|
|
||||||
|
|
||||||
C_NONE = 0,
|
C_NONE = 0,
|
||||||
C_REG,
|
C_REG,
|
||||||
|
|
@ -221,21 +218,16 @@ enum
|
||||||
C_RCON, /* 0xff rotated */
|
C_RCON, /* 0xff rotated */
|
||||||
C_NCON, /* ~RCON */
|
C_NCON, /* ~RCON */
|
||||||
C_SCON, /* 0xffff */
|
C_SCON, /* 0xffff */
|
||||||
C_BCON, /* thumb */
|
|
||||||
C_LCON,
|
C_LCON,
|
||||||
C_ZFCON,
|
C_ZFCON,
|
||||||
C_SFCON,
|
C_SFCON,
|
||||||
C_LFCON,
|
C_LFCON,
|
||||||
C_GCON, /* thumb */
|
|
||||||
|
|
||||||
C_RACON,
|
C_RACON,
|
||||||
C_SACON, /* thumb */
|
|
||||||
C_LACON,
|
C_LACON,
|
||||||
C_GACON, /* thumb */
|
|
||||||
|
|
||||||
C_SBRA,
|
C_SBRA,
|
||||||
C_LBRA,
|
C_LBRA,
|
||||||
C_GBRA, /* thumb */
|
|
||||||
|
|
||||||
C_HAUTO, /* halfword insn offset (-0xff to 0xff) */
|
C_HAUTO, /* halfword insn offset (-0xff to 0xff) */
|
||||||
C_FAUTO, /* float insn offset (0 to 0x3fc, word aligned) */
|
C_FAUTO, /* float insn offset (0 to 0x3fc, word aligned) */
|
||||||
|
|
@ -250,12 +242,10 @@ enum
|
||||||
C_ROREG,
|
C_ROREG,
|
||||||
C_SROREG, /* both S and R */
|
C_SROREG, /* both S and R */
|
||||||
C_LOREG,
|
C_LOREG,
|
||||||
C_GOREG, /* thumb */
|
|
||||||
|
|
||||||
C_PC,
|
C_PC,
|
||||||
C_SP,
|
C_SP,
|
||||||
C_HREG,
|
C_HREG,
|
||||||
C_OFFPC, /* thumb */
|
|
||||||
|
|
||||||
C_ADDR, /* reference to relocatable address */
|
C_ADDR, /* reference to relocatable address */
|
||||||
|
|
||||||
|
|
@ -287,9 +277,6 @@ EXTERN union
|
||||||
#define cbuf u.obuf
|
#define cbuf u.obuf
|
||||||
#define xbuf u.ibuf
|
#define xbuf u.ibuf
|
||||||
|
|
||||||
#define setarch(p) if((p)->as==ATEXT) thumb=(p)->reg&ALLTHUMBS
|
|
||||||
#define setthumb(p) if((p)->as==ATEXT) seenthumb|=(p)->reg&ALLTHUMBS
|
|
||||||
|
|
||||||
#ifndef COFFCVT
|
#ifndef COFFCVT
|
||||||
|
|
||||||
EXTERN int32 HEADR; /* length of header */
|
EXTERN int32 HEADR; /* length of header */
|
||||||
|
|
@ -319,7 +306,6 @@ EXTERN int nerrors;
|
||||||
EXTERN int32 instoffset;
|
EXTERN int32 instoffset;
|
||||||
EXTERN Opcross opcross[8];
|
EXTERN Opcross opcross[8];
|
||||||
EXTERN Oprang oprange[ALAST];
|
EXTERN Oprang oprange[ALAST];
|
||||||
EXTERN Oprang thumboprange[ALAST];
|
|
||||||
EXTERN char* outfile;
|
EXTERN char* outfile;
|
||||||
EXTERN int32 pc;
|
EXTERN int32 pc;
|
||||||
EXTERN uchar repop[ALAST];
|
EXTERN uchar repop[ALAST];
|
||||||
|
|
@ -333,14 +319,10 @@ EXTERN int version;
|
||||||
EXTERN char xcmp[C_GOK+1][C_GOK+1];
|
EXTERN char xcmp[C_GOK+1][C_GOK+1];
|
||||||
EXTERN Prog zprg;
|
EXTERN Prog zprg;
|
||||||
EXTERN int dtype;
|
EXTERN int dtype;
|
||||||
EXTERN int armv4;
|
|
||||||
EXTERN int thumb;
|
|
||||||
EXTERN int seenthumb;
|
|
||||||
EXTERN int armsize;
|
EXTERN int armsize;
|
||||||
|
|
||||||
extern char* anames[];
|
extern char* anames[];
|
||||||
extern Optab optab[];
|
extern Optab optab[];
|
||||||
extern Optab thumboptab[];
|
|
||||||
|
|
||||||
void addpool(Prog*, Adr*);
|
void addpool(Prog*, Adr*);
|
||||||
EXTERN Prog* blitrl;
|
EXTERN Prog* blitrl;
|
||||||
|
|
@ -368,17 +350,13 @@ int Oconv(Fmt*);
|
||||||
int Pconv(Fmt*);
|
int Pconv(Fmt*);
|
||||||
int Sconv(Fmt*);
|
int Sconv(Fmt*);
|
||||||
int aclass(Adr*);
|
int aclass(Adr*);
|
||||||
int thumbaclass(Adr*, Prog*);
|
|
||||||
void addhist(int32, int);
|
void addhist(int32, int);
|
||||||
Prog* appendp(Prog*);
|
Prog* appendp(Prog*);
|
||||||
void asmb(void);
|
void asmb(void);
|
||||||
void asmthumbmap(void);
|
|
||||||
void asmout(Prog*, Optab*, int32*);
|
void asmout(Prog*, Optab*, int32*);
|
||||||
void thumbasmout(Prog*, Optab*);
|
|
||||||
int32 atolwhex(char*);
|
int32 atolwhex(char*);
|
||||||
Prog* brloop(Prog*);
|
Prog* brloop(Prog*);
|
||||||
void buildop(void);
|
void buildop(void);
|
||||||
void thumbbuildop(void);
|
|
||||||
void buildrep(int, int);
|
void buildrep(int, int);
|
||||||
void cflush(void);
|
void cflush(void);
|
||||||
int chipzero(Ieee*);
|
int chipzero(Ieee*);
|
||||||
|
|
@ -442,9 +420,6 @@ int32 immaddr(int32);
|
||||||
int32 opbra(int, int);
|
int32 opbra(int, int);
|
||||||
int brextra(Prog*);
|
int brextra(Prog*);
|
||||||
int isbranch(Prog*);
|
int isbranch(Prog*);
|
||||||
int fnpinc(Sym *);
|
|
||||||
int fninc(Sym *);
|
|
||||||
void thumbcount(void);
|
|
||||||
void fnptrs(void);
|
void fnptrs(void);
|
||||||
void doelf(void);
|
void doelf(void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -412,7 +412,6 @@ static char*
|
||||||
cnames[] =
|
cnames[] =
|
||||||
{
|
{
|
||||||
[C_ADDR] = "C_ADDR",
|
[C_ADDR] = "C_ADDR",
|
||||||
[C_BCON] = "C_BCON",
|
|
||||||
[C_FAUTO] = "C_FAUTO",
|
[C_FAUTO] = "C_FAUTO",
|
||||||
[C_ZFCON] = "C_SFCON",
|
[C_ZFCON] = "C_SFCON",
|
||||||
[C_SFCON] = "C_SFCON",
|
[C_SFCON] = "C_SFCON",
|
||||||
|
|
@ -420,11 +419,7 @@ cnames[] =
|
||||||
[C_FCR] = "C_FCR",
|
[C_FCR] = "C_FCR",
|
||||||
[C_FOREG] = "C_FOREG",
|
[C_FOREG] = "C_FOREG",
|
||||||
[C_FREG] = "C_FREG",
|
[C_FREG] = "C_FREG",
|
||||||
[C_GACON] = "C_GACON",
|
|
||||||
[C_GBRA] = "C_GBRA",
|
|
||||||
[C_GCON] = "C_GCON",
|
|
||||||
[C_GOK] = "C_GOK",
|
[C_GOK] = "C_GOK",
|
||||||
[C_GOREG] = "C_GOREG",
|
|
||||||
[C_HAUTO] = "C_HAUTO",
|
[C_HAUTO] = "C_HAUTO",
|
||||||
[C_HFAUTO] = "C_HFAUTO",
|
[C_HFAUTO] = "C_HFAUTO",
|
||||||
[C_HFOREG] = "C_HFOREG",
|
[C_HFOREG] = "C_HFOREG",
|
||||||
|
|
@ -437,7 +432,6 @@ cnames[] =
|
||||||
[C_LOREG] = "C_LOREG",
|
[C_LOREG] = "C_LOREG",
|
||||||
[C_NCON] = "C_NCON",
|
[C_NCON] = "C_NCON",
|
||||||
[C_NONE] = "C_NONE",
|
[C_NONE] = "C_NONE",
|
||||||
[C_OFFPC] = "C_OFFPC",
|
|
||||||
[C_PC] = "C_PC",
|
[C_PC] = "C_PC",
|
||||||
[C_PSR] = "C_PSR",
|
[C_PSR] = "C_PSR",
|
||||||
[C_RACON] = "C_RACON",
|
[C_RACON] = "C_RACON",
|
||||||
|
|
@ -445,7 +439,6 @@ cnames[] =
|
||||||
[C_REG] = "C_REG",
|
[C_REG] = "C_REG",
|
||||||
[C_REGREG] = "C_REGREG",
|
[C_REGREG] = "C_REGREG",
|
||||||
[C_ROREG] = "C_ROREG",
|
[C_ROREG] = "C_ROREG",
|
||||||
[C_SACON] = "C_SACON",
|
|
||||||
[C_SAUTO] = "C_SAUTO",
|
[C_SAUTO] = "C_SAUTO",
|
||||||
[C_SBRA] = "C_SBRA",
|
[C_SBRA] = "C_SBRA",
|
||||||
[C_SCON] = "C_SCON",
|
[C_SCON] = "C_SCON",
|
||||||
|
|
|
||||||
|
|
@ -47,74 +47,11 @@ static Sym* sym_modu;
|
||||||
|
|
||||||
static void setdiv(int);
|
static void setdiv(int);
|
||||||
|
|
||||||
static Prog *
|
|
||||||
movrr(Prog *q, int rs, int rd, Prog *p)
|
|
||||||
{
|
|
||||||
if(q == nil)
|
|
||||||
q = prg();
|
|
||||||
q->as = AMOVW;
|
|
||||||
q->line = p->line;
|
|
||||||
q->from.type = D_REG;
|
|
||||||
q->from.reg = rs;
|
|
||||||
q->to.type = D_REG;
|
|
||||||
q->to.reg = rd;
|
|
||||||
q->link = p->link;
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Prog *
|
|
||||||
fnret(Prog *q, int rs, int foreign, Prog *p)
|
|
||||||
{
|
|
||||||
q = movrr(q, rs, REGPC, p);
|
|
||||||
if(foreign){ // BX rs
|
|
||||||
q->as = ABXRET;
|
|
||||||
q->from.type = D_NONE;
|
|
||||||
q->from.reg = NREG;
|
|
||||||
q->to.reg = rs;
|
|
||||||
}
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Prog *
|
|
||||||
aword(int32 w, Prog *p)
|
|
||||||
{
|
|
||||||
Prog *q;
|
|
||||||
|
|
||||||
q = prg();
|
|
||||||
q->as = AWORD;
|
|
||||||
q->line = p->line;
|
|
||||||
q->from.type = D_NONE;
|
|
||||||
q->reg = NREG;
|
|
||||||
q->to.type = D_CONST;
|
|
||||||
q->to.offset = w;
|
|
||||||
q->link = p->link;
|
|
||||||
p->link = q;
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Prog *
|
|
||||||
adword(int32 w1, int32 w2, Prog *p)
|
|
||||||
{
|
|
||||||
Prog *q;
|
|
||||||
|
|
||||||
q = prg();
|
|
||||||
q->as = ADWORD;
|
|
||||||
q->line = p->line;
|
|
||||||
q->from.type = D_CONST;
|
|
||||||
q->from.offset = w1;
|
|
||||||
q->reg = NREG;
|
|
||||||
q->to.type = D_CONST;
|
|
||||||
q->to.offset = w2;
|
|
||||||
q->link = p->link;
|
|
||||||
p->link = q;
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
noops(void)
|
noops(void)
|
||||||
{
|
{
|
||||||
Prog *p, *q, *q1, *q2;
|
Prog *p, *q, *q1;
|
||||||
int o, foreign;
|
int o;
|
||||||
Prog *pmorestack;
|
Prog *pmorestack;
|
||||||
Sym *symmorestack;
|
Sym *symmorestack;
|
||||||
|
|
||||||
|
|
@ -140,8 +77,6 @@ noops(void)
|
||||||
q = P;
|
q = P;
|
||||||
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
||||||
for(p = cursym->text; p != P; p = p->link) {
|
for(p = cursym->text; p != P; p = p->link) {
|
||||||
setarch(p);
|
|
||||||
|
|
||||||
switch(p->as) {
|
switch(p->as) {
|
||||||
case ATEXT:
|
case ATEXT:
|
||||||
p->mark |= LEAF;
|
p->mark |= LEAF;
|
||||||
|
|
@ -206,7 +141,6 @@ noops(void)
|
||||||
|
|
||||||
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
||||||
for(p = cursym->text; p != P; p = p->link) {
|
for(p = cursym->text; p != P; p = p->link) {
|
||||||
setarch(p);
|
|
||||||
o = p->as;
|
o = p->as;
|
||||||
switch(o) {
|
switch(o) {
|
||||||
case ATEXT:
|
case ATEXT:
|
||||||
|
|
@ -224,54 +158,12 @@ noops(void)
|
||||||
Bflush(&bso);
|
Bflush(&bso);
|
||||||
cursym->text->mark |= LEAF;
|
cursym->text->mark |= LEAF;
|
||||||
}
|
}
|
||||||
#ifdef CALLEEBX
|
|
||||||
if(p->from.sym->foreign){
|
|
||||||
if(thumb)
|
|
||||||
// don't allow literal pool to separate these
|
|
||||||
p = adword(0xe28f7001, 0xe12fff17, p); // arm add 1, pc, r7 and bx r7
|
|
||||||
// p = aword(0xe12fff17, aword(0xe28f7001, p)); // arm add 1, pc, r7 and bx r7
|
|
||||||
else
|
|
||||||
p = aword(0x4778, p); // thumb bx pc and 2 bytes padding
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(cursym->text->mark & LEAF) {
|
if(cursym->text->mark & LEAF) {
|
||||||
cursym->leaf = 1;
|
cursym->leaf = 1;
|
||||||
if(!autosize)
|
if(!autosize)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thumb){
|
|
||||||
if(!(p->reg & NOSPLIT))
|
|
||||||
diag("stack splitting not supported in thumb");
|
|
||||||
if(!(cursym->text->mark & LEAF)){
|
|
||||||
q = movrr(nil, REGLINK, REGTMPT-1, p);
|
|
||||||
p->link = q;
|
|
||||||
q1 = prg();
|
|
||||||
q1->as = AMOVW;
|
|
||||||
q1->line = p->line;
|
|
||||||
q1->from.type = D_REG;
|
|
||||||
q1->from.reg = REGTMPT-1;
|
|
||||||
q1->to.type = D_OREG;
|
|
||||||
q1->to.name = D_NONE;
|
|
||||||
q1->to.reg = REGSP;
|
|
||||||
q1->to.offset = 0;
|
|
||||||
q1->link = q->link;
|
|
||||||
q->link = q1;
|
|
||||||
}
|
|
||||||
if(autosize){
|
|
||||||
q2 = prg();
|
|
||||||
q2->as = ASUB;
|
|
||||||
q2->line = p->line;
|
|
||||||
q2->from.type = D_CONST;
|
|
||||||
q2->from.offset = autosize;
|
|
||||||
q2->to.type = D_REG;
|
|
||||||
q2->to.reg = REGSP;
|
|
||||||
q2->link = p->link;
|
|
||||||
p->link = q2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p->reg & NOSPLIT) {
|
if(p->reg & NOSPLIT) {
|
||||||
q1 = prg();
|
q1 = prg();
|
||||||
q1->as = AMOVW;
|
q1->as = AMOVW;
|
||||||
|
|
@ -432,16 +324,9 @@ noops(void)
|
||||||
|
|
||||||
case ARET:
|
case ARET:
|
||||||
nocache(p);
|
nocache(p);
|
||||||
foreign = seenthumb && (cursym->foreign || cursym->fnptr);
|
|
||||||
// print("%s %d %d\n", cursym->name, cursym->foreign, cursym->fnptr);
|
|
||||||
if(cursym->text->mark & LEAF) {
|
if(cursym->text->mark & LEAF) {
|
||||||
if(!autosize) {
|
if(!autosize) {
|
||||||
if(thumb){
|
p->as = AB;
|
||||||
p = fnret(p, REGLINK, foreign, p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// if(foreign) print("ABXRET 1 %s\n", cursym->name);
|
|
||||||
p->as = foreign ? ABXRET : AB;
|
|
||||||
p->from = zprg.from;
|
p->from = zprg.from;
|
||||||
p->to.type = D_OREG;
|
p->to.type = D_OREG;
|
||||||
p->to.offset = 0;
|
p->to.offset = 0;
|
||||||
|
|
@ -449,95 +334,16 @@ noops(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(thumb){
|
p->as = AMOVW;
|
||||||
diag("thumb not maintained");
|
p->scond |= C_PBIT;
|
||||||
errorexit();
|
p->from.type = D_OREG;
|
||||||
if(cursym->text->mark & LEAF){
|
p->from.offset = autosize;
|
||||||
if(autosize){
|
p->from.reg = REGSP;
|
||||||
p->as = AADD;
|
p->to.type = D_REG;
|
||||||
p->from.type = D_CONST;
|
p->to.reg = REGPC;
|
||||||
p->from.offset = autosize;
|
// If there are instructions following
|
||||||
p->to.type = D_REG;
|
// this ARET, they come from a branch
|
||||||
p->to.reg = REGSP;
|
// with the same stackframe, so no spadj.
|
||||||
q = nil;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
q = p;
|
|
||||||
q = fnret(q, REGLINK, foreign, p);
|
|
||||||
if(q != p)
|
|
||||||
p->link = q;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
p->as = AMOVW;
|
|
||||||
p->from.type = D_OREG;
|
|
||||||
p->from.name = D_NONE;
|
|
||||||
p->from.reg = REGSP;
|
|
||||||
p->from.offset = 0;
|
|
||||||
p->to.type = D_REG;
|
|
||||||
p->to.reg = REGTMPT-1;
|
|
||||||
if(autosize){
|
|
||||||
q = prg();
|
|
||||||
q->as = AADD;
|
|
||||||
q->from.type = D_CONST;
|
|
||||||
q->from.offset = autosize;
|
|
||||||
q->to.type = D_REG;
|
|
||||||
q->to.reg = REGSP;
|
|
||||||
q->link = p->link;
|
|
||||||
p->link = q;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
q = p;
|
|
||||||
q1 = fnret(nil, REGTMPT-1, foreign, p);
|
|
||||||
q1->link = q->link;
|
|
||||||
q->link = q1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(foreign) {
|
|
||||||
diag("foreign not maintained");
|
|
||||||
errorexit();
|
|
||||||
// if(foreign) print("ABXRET 3 %s\n", cursym->name);
|
|
||||||
#define R 1
|
|
||||||
p->as = AMOVW;
|
|
||||||
p->from.type = D_OREG;
|
|
||||||
p->from.name = D_NONE;
|
|
||||||
p->from.reg = REGSP;
|
|
||||||
p->from.offset = 0;
|
|
||||||
p->to.type = D_REG;
|
|
||||||
p->to.reg = R;
|
|
||||||
q = prg();
|
|
||||||
q->as = AADD;
|
|
||||||
q->scond = p->scond;
|
|
||||||
q->line = p->line;
|
|
||||||
q->from.type = D_CONST;
|
|
||||||
q->from.offset = autosize;
|
|
||||||
q->to.type = D_REG;
|
|
||||||
q->to.reg = REGSP;
|
|
||||||
q->link = p->link;
|
|
||||||
p->link = q;
|
|
||||||
q1 = prg();
|
|
||||||
q1->as = ABXRET;
|
|
||||||
q1->scond = p->scond;
|
|
||||||
q1->line = p->line;
|
|
||||||
q1->to.type = D_OREG;
|
|
||||||
q1->to.offset = 0;
|
|
||||||
q1->to.reg = R;
|
|
||||||
q1->link = q->link;
|
|
||||||
q->link = q1;
|
|
||||||
#undef R
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
p->as = AMOVW;
|
|
||||||
p->scond |= C_PBIT;
|
|
||||||
p->from.type = D_OREG;
|
|
||||||
p->from.offset = autosize;
|
|
||||||
p->from.reg = REGSP;
|
|
||||||
p->to.type = D_REG;
|
|
||||||
p->to.reg = REGPC;
|
|
||||||
// If there are instructions following
|
|
||||||
// this ARET, they come from a branch
|
|
||||||
// with the same stackframe, so no spadj.
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AADD:
|
case AADD:
|
||||||
|
|
@ -589,7 +395,7 @@ noops(void)
|
||||||
if(q1->reg == NREG)
|
if(q1->reg == NREG)
|
||||||
p->from.reg = q1->to.reg;
|
p->from.reg = q1->to.reg;
|
||||||
p->to.type = D_REG;
|
p->to.type = D_REG;
|
||||||
p->to.reg = prog_div->from.sym->thumb ? REGTMPT : REGTMP;
|
p->to.reg = REGTMP;
|
||||||
p->to.offset = 0;
|
p->to.offset = 0;
|
||||||
|
|
||||||
/* CALL appropriate */
|
/* CALL appropriate */
|
||||||
|
|
@ -598,14 +404,7 @@ noops(void)
|
||||||
p->link = q;
|
p->link = q;
|
||||||
p = q;
|
p = q;
|
||||||
|
|
||||||
#ifdef CALLEEBX
|
|
||||||
p->as = ABL;
|
p->as = ABL;
|
||||||
#else
|
|
||||||
if(prog_div->from.sym->thumb)
|
|
||||||
p->as = thumb ? ABL : ABX;
|
|
||||||
else
|
|
||||||
p->as = thumb ? ABX : ABL;
|
|
||||||
#endif
|
|
||||||
p->line = q1->line;
|
p->line = q1->line;
|
||||||
p->to.type = D_BRANCH;
|
p->to.type = D_BRANCH;
|
||||||
p->cond = p;
|
p->cond = p;
|
||||||
|
|
@ -637,7 +436,7 @@ noops(void)
|
||||||
p->as = AMOVW;
|
p->as = AMOVW;
|
||||||
p->line = q1->line;
|
p->line = q1->line;
|
||||||
p->from.type = D_REG;
|
p->from.type = D_REG;
|
||||||
p->from.reg = prog_div->from.sym->thumb ? REGTMPT : REGTMP;
|
p->from.reg = REGTMP;
|
||||||
p->from.offset = 0;
|
p->from.offset = 0;
|
||||||
p->to.type = D_REG;
|
p->to.type = D_REG;
|
||||||
p->to.reg = q1->to.reg;
|
p->to.reg = q1->to.reg;
|
||||||
|
|
@ -669,12 +468,6 @@ noops(void)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case AMOVW:
|
case AMOVW:
|
||||||
if(thumb){
|
|
||||||
Adr *a = &p->from;
|
|
||||||
|
|
||||||
if(a->type == D_CONST && ((a->name == D_NONE && a->reg == REGSP) || a->name == D_AUTO || a->name == D_PARAM) && (a->offset & 3))
|
|
||||||
diag("SP offset not multiple of 4");
|
|
||||||
}
|
|
||||||
if((p->scond & C_WBIT) && p->to.type == D_OREG && p->to.reg == REGSP)
|
if((p->scond & C_WBIT) && p->to.type == D_OREG && p->to.reg == REGSP)
|
||||||
p->spadj = -p->to.offset;
|
p->spadj = -p->to.offset;
|
||||||
if((p->scond & C_PBIT) && p->from.type == D_OREG && p->from.reg == REGSP && p->to.reg != REGPC)
|
if((p->scond & C_PBIT) && p->from.type == D_OREG && p->from.reg == REGSP && p->to.reg != REGPC)
|
||||||
|
|
@ -682,136 +475,6 @@ noops(void)
|
||||||
if(p->from.type == D_CONST && p->from.reg == REGSP && p->to.type == D_REG && p->to.reg == REGSP)
|
if(p->from.type == D_CONST && p->from.reg == REGSP && p->to.type == D_REG && p->to.reg == REGSP)
|
||||||
p->spadj = -p->from.offset;
|
p->spadj = -p->from.offset;
|
||||||
break;
|
break;
|
||||||
case AMOVB:
|
|
||||||
case AMOVBU:
|
|
||||||
case AMOVH:
|
|
||||||
case AMOVHU:
|
|
||||||
if(thumb){
|
|
||||||
if(p->from.type == D_OREG && (p->from.name == D_AUTO || p->from.name == D_PARAM || (p->from.name == D_CONST && p->from.reg == REGSP))){
|
|
||||||
q = prg();
|
|
||||||
*q = *p;
|
|
||||||
if(p->from.name == D_AUTO)
|
|
||||||
q->from.offset += autosize;
|
|
||||||
else if(p->from.name == D_PARAM)
|
|
||||||
q->from.offset += autosize+4;
|
|
||||||
q->from.name = D_NONE;
|
|
||||||
q->from.reg = REGTMPT;
|
|
||||||
p = movrr(p, REGSP, REGTMPT, p);
|
|
||||||
q->link = p->link;
|
|
||||||
p->link = q;
|
|
||||||
}
|
|
||||||
if(p->to.type == D_OREG && (p->to.name == D_AUTO || p->to.name == D_PARAM || (p->to.name == D_CONST && p->to.reg == REGSP))){
|
|
||||||
q = prg();
|
|
||||||
*q = *p;
|
|
||||||
if(p->to.name == D_AUTO)
|
|
||||||
q->to.offset += autosize;
|
|
||||||
else if(p->to.name == D_PARAM)
|
|
||||||
q->to.offset += autosize+4;
|
|
||||||
q->to.name = D_NONE;
|
|
||||||
q->to.reg = REGTMPT;
|
|
||||||
p = movrr(p, REGSP, REGTMPT, p);
|
|
||||||
q->link = p->link;
|
|
||||||
p->link = q;
|
|
||||||
if(q->to.offset < 0 || q->to.offset > 255){ // complicated
|
|
||||||
p->to.reg = REGTMPT+1; // mov sp, r8
|
|
||||||
q1 = prg();
|
|
||||||
q1->line = p->line;
|
|
||||||
q1->as = AMOVW;
|
|
||||||
q1->from.type = D_CONST;
|
|
||||||
q1->from.offset = q->to.offset;
|
|
||||||
q1->to.type = D_REG;
|
|
||||||
q1->to.reg = REGTMPT; // mov $o, r7
|
|
||||||
p->link = q1;
|
|
||||||
q1->link = q;
|
|
||||||
q1 = prg();
|
|
||||||
q1->line = p->line;
|
|
||||||
q1->as = AADD;
|
|
||||||
q1->from.type = D_REG;
|
|
||||||
q1->from.reg = REGTMPT+1;
|
|
||||||
q1->to.type = D_REG;
|
|
||||||
q1->to.reg = REGTMPT; // add r8, r7
|
|
||||||
p->link->link = q1;
|
|
||||||
q1->link = q;
|
|
||||||
q->to.offset = 0; // mov* r, 0(r7)
|
|
||||||
/* phew */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AMOVM:
|
|
||||||
if(thumb){
|
|
||||||
if(p->from.type == D_OREG){
|
|
||||||
if(p->from.offset == 0)
|
|
||||||
p->from.type = D_REG;
|
|
||||||
else
|
|
||||||
diag("non-zero AMOVM offset");
|
|
||||||
}
|
|
||||||
else if(p->to.type == D_OREG){
|
|
||||||
if(p->to.offset == 0)
|
|
||||||
p->to.type = D_REG;
|
|
||||||
else
|
|
||||||
diag("non-zero AMOVM offset");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AB:
|
|
||||||
if(thumb && p->to.type == D_OREG){
|
|
||||||
if(p->to.offset == 0){
|
|
||||||
p->as = AMOVW;
|
|
||||||
p->from.type = D_REG;
|
|
||||||
p->from.reg = p->to.reg;
|
|
||||||
p->to.type = D_REG;
|
|
||||||
p->to.reg = REGPC;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
p->as = AADD;
|
|
||||||
p->from.type = D_CONST;
|
|
||||||
p->from.offset = p->to.offset;
|
|
||||||
p->reg = p->to.reg;
|
|
||||||
p->to.type = D_REG;
|
|
||||||
p->to.reg = REGTMPT-1;
|
|
||||||
q = prg();
|
|
||||||
q->as = AMOVW;
|
|
||||||
q->line = p->line;
|
|
||||||
q->from.type = D_REG;
|
|
||||||
q->from.reg = REGTMPT-1;
|
|
||||||
q->to.type = D_REG;
|
|
||||||
q->to.reg = REGPC;
|
|
||||||
q->link = p->link;
|
|
||||||
p->link = q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(seenthumb && !thumb && p->to.type == D_OREG && p->to.reg == REGLINK){
|
|
||||||
// print("warn %s: b (R%d) assuming a return\n", cursym->name, p->to.reg);
|
|
||||||
p->as = ABXRET;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ABL:
|
|
||||||
case ABX:
|
|
||||||
if(thumb && p->to.type == D_OREG){
|
|
||||||
if(p->to.offset == 0){
|
|
||||||
p->as = o;
|
|
||||||
p->from.type = D_NONE;
|
|
||||||
p->to.type = D_REG;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
p->as = AADD;
|
|
||||||
p->from.type = D_CONST;
|
|
||||||
p->from.offset = p->to.offset;
|
|
||||||
p->reg = p->to.reg;
|
|
||||||
p->to.type = D_REG;
|
|
||||||
p->to.reg = REGTMPT-1;
|
|
||||||
q = prg();
|
|
||||||
q->as = o;
|
|
||||||
q->line = p->line;
|
|
||||||
q->from.type = D_NONE;
|
|
||||||
q->to.type = D_REG;
|
|
||||||
q->to.reg = REGTMPT-1;
|
|
||||||
q->link = p->link;
|
|
||||||
p->link = q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -876,13 +539,19 @@ setdiv(int as)
|
||||||
Prog *p = nil;
|
Prog *p = nil;
|
||||||
|
|
||||||
switch(as){
|
switch(as){
|
||||||
case ADIV: p = prog_div; break;
|
case ADIV:
|
||||||
case ADIVU: p = prog_divu; break;
|
p = prog_div;
|
||||||
case AMOD: p = prog_mod; break;
|
break;
|
||||||
case AMODU: p = prog_modu; break;
|
case ADIVU:
|
||||||
|
p = prog_divu;
|
||||||
|
break;
|
||||||
|
case AMOD:
|
||||||
|
p = prog_mod;
|
||||||
|
break;
|
||||||
|
case AMODU:
|
||||||
|
p = prog_modu;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(thumb != p->from.sym->thumb)
|
|
||||||
p->from.sym->foreign = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,6 @@ main(int argc, char *argv[])
|
||||||
zprg.from.reg = NREG;
|
zprg.from.reg = NREG;
|
||||||
zprg.to = zprg.from;
|
zprg.to = zprg.from;
|
||||||
buildop();
|
buildop();
|
||||||
thumbbuildop(); // could build on demand
|
|
||||||
histgen = 0;
|
histgen = 0;
|
||||||
pc = 0;
|
pc = 0;
|
||||||
dtype = 4;
|
dtype = 4;
|
||||||
|
|
@ -286,10 +285,8 @@ main(int argc, char *argv[])
|
||||||
asmb();
|
asmb();
|
||||||
undef();
|
undef();
|
||||||
|
|
||||||
if(debug['c']){
|
if(debug['c'])
|
||||||
thumbcount();
|
|
||||||
print("ARM size = %d\n", armsize);
|
print("ARM size = %d\n", armsize);
|
||||||
}
|
|
||||||
if(debug['v']) {
|
if(debug['v']) {
|
||||||
Bprint(&bso, "%5.2f cpu time\n", cputime());
|
Bprint(&bso, "%5.2f cpu time\n", cputime());
|
||||||
Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
|
Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
|
||||||
|
|
@ -406,8 +403,6 @@ nopout(Prog *p)
|
||||||
p->to.type = D_NONE;
|
p->to.type = D_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void puntfp(Prog *);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
|
ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
|
||||||
{
|
{
|
||||||
|
|
@ -622,8 +617,6 @@ loop:
|
||||||
else
|
else
|
||||||
textp = s;
|
textp = s;
|
||||||
etextp = s;
|
etextp = s;
|
||||||
setarch(p);
|
|
||||||
setthumb(p);
|
|
||||||
p->align = 4;
|
p->align = 4;
|
||||||
autosize = (p->to.offset+3L) & ~3L;
|
autosize = (p->to.offset+3L) & ~3L;
|
||||||
p->to.offset = autosize;
|
p->to.offset = autosize;
|
||||||
|
|
@ -631,7 +624,6 @@ loop:
|
||||||
s->type = STEXT;
|
s->type = STEXT;
|
||||||
s->text = p;
|
s->text = p;
|
||||||
s->value = pc;
|
s->value = pc;
|
||||||
s->thumb = thumb;
|
|
||||||
lastp = p;
|
lastp = p;
|
||||||
p->pc = pc;
|
p->pc = pc;
|
||||||
pc++;
|
pc++;
|
||||||
|
|
@ -673,13 +665,9 @@ loop:
|
||||||
case AMULD:
|
case AMULD:
|
||||||
case ADIVF:
|
case ADIVF:
|
||||||
case ADIVD:
|
case ADIVD:
|
||||||
if(thumb)
|
|
||||||
puntfp(p);
|
|
||||||
goto casedef;
|
goto casedef;
|
||||||
|
|
||||||
case AMOVF:
|
case AMOVF:
|
||||||
if(thumb)
|
|
||||||
puntfp(p);
|
|
||||||
if(skip)
|
if(skip)
|
||||||
goto casedef;
|
goto casedef;
|
||||||
|
|
||||||
|
|
@ -701,8 +689,6 @@ loop:
|
||||||
goto casedef;
|
goto casedef;
|
||||||
|
|
||||||
case AMOVD:
|
case AMOVD:
|
||||||
if(thumb)
|
|
||||||
puntfp(p);
|
|
||||||
if(skip)
|
if(skip)
|
||||||
goto casedef;
|
goto casedef;
|
||||||
|
|
||||||
|
|
@ -758,17 +744,6 @@ prg(void)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
puntfp(Prog *p)
|
|
||||||
{
|
|
||||||
USED(p);
|
|
||||||
/* floating point - punt for now */
|
|
||||||
cursym->text->reg = NREG; /* ARM */
|
|
||||||
cursym->thumb = 0;
|
|
||||||
thumb = 0;
|
|
||||||
// print("%s: generating ARM code (contains floating point ops %d)\n", curtext->from.sym->name, p->line);
|
|
||||||
}
|
|
||||||
|
|
||||||
Prog*
|
Prog*
|
||||||
appendp(Prog *q)
|
appendp(Prog *q)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,6 @@ Optab optab[] =
|
||||||
{ ASWI, C_NONE, C_NONE, C_LCON, 10, 4, 0 },
|
{ ASWI, C_NONE, C_NONE, C_LCON, 10, 4, 0 },
|
||||||
|
|
||||||
{ AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0 },
|
{ AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0 },
|
||||||
{ AWORD, C_NONE, C_NONE, C_GCON, 11, 4, 0 },
|
|
||||||
{ AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0 },
|
{ AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0 },
|
||||||
|
|
||||||
{ AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0 },
|
{ AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0 },
|
||||||
|
|
@ -181,34 +180,34 @@ Optab optab[] =
|
||||||
{ ACASE, C_REG, C_NONE, C_NONE, 62, 4, 0 },
|
{ ACASE, C_REG, C_NONE, C_NONE, 62, 4, 0 },
|
||||||
{ ABCASE, C_NONE, C_NONE, C_SBRA, 63, 4, 0 },
|
{ ABCASE, C_NONE, C_NONE, C_SBRA, 63, 4, 0 },
|
||||||
|
|
||||||
{ AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, V4 },
|
{ AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0 },
|
||||||
{ AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, V4 },
|
{ AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0 },
|
||||||
{ AMOVHU, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, V4 },
|
{ AMOVHU, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0 },
|
||||||
{ AMOVHU, C_REG, C_NONE, C_HOREG, 70, 4, 0, V4 },
|
{ AMOVHU, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0 },
|
||||||
|
|
||||||
{ AMOVB, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, V4 },
|
{ AMOVB, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, 0 },
|
||||||
{ AMOVB, C_HOREG,C_NONE, C_REG, 71, 4, 0, V4 },
|
{ AMOVB, C_HOREG,C_NONE, C_REG, 71, 4, 0, 0 },
|
||||||
{ AMOVH, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, V4 },
|
{ AMOVH, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, 0 },
|
||||||
{ AMOVH, C_HOREG,C_NONE, C_REG, 71, 4, 0, V4 },
|
{ AMOVH, C_HOREG,C_NONE, C_REG, 71, 4, 0, 0 },
|
||||||
{ AMOVHU, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, V4 },
|
{ AMOVHU, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, 0 },
|
||||||
{ AMOVHU, C_HOREG,C_NONE, C_REG, 71, 4, 0, V4 },
|
{ AMOVHU, C_HOREG,C_NONE, C_REG, 71, 4, 0, 0 },
|
||||||
|
|
||||||
{ AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO|V4 },
|
{ AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO },
|
||||||
{ AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO|V4 },
|
{ AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO },
|
||||||
{ AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO|V4 },
|
{ AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO },
|
||||||
{ AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO|V4 },
|
{ AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO },
|
||||||
{ AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO|V4 },
|
{ AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO },
|
||||||
{ AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO|V4 },
|
{ AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO },
|
||||||
|
|
||||||
{ AMOVB, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM|V4 },
|
{ AMOVB, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
|
||||||
{ AMOVB, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM|V4 },
|
{ AMOVB, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
|
||||||
{ AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM|V4 },
|
{ AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM },
|
||||||
{ AMOVH, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM|V4 },
|
{ AMOVH, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
|
||||||
{ AMOVH, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM|V4 },
|
{ AMOVH, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
|
||||||
{ AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM|V4 },
|
{ AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM },
|
||||||
{ AMOVHU, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM|V4 },
|
{ AMOVHU, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
|
||||||
{ AMOVHU, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM|V4 },
|
{ AMOVHU, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
|
||||||
{ AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM|V4 },
|
{ AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM },
|
||||||
|
|
||||||
{ ALDREX, C_SOREG,C_NONE, C_REG, 77, 4, 0 },
|
{ ALDREX, C_SOREG,C_NONE, C_REG, 77, 4, 0 },
|
||||||
{ ASTREX, C_SOREG,C_REG, C_REG, 78, 4, 0 },
|
{ ASTREX, C_SOREG,C_REG, C_REG, 78, 4, 0 },
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,6 @@ xfol(Prog *p, Prog **last)
|
||||||
loop:
|
loop:
|
||||||
if(p == P)
|
if(p == P)
|
||||||
return;
|
return;
|
||||||
setarch(p);
|
|
||||||
a = p->as;
|
a = p->as;
|
||||||
if(a == AB) {
|
if(a == AB) {
|
||||||
q = p->cond;
|
q = p->cond;
|
||||||
|
|
@ -210,14 +209,7 @@ patch(void)
|
||||||
vexit = s->value;
|
vexit = s->value;
|
||||||
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
||||||
for(p = cursym->text; p != P; p = p->link) {
|
for(p = cursym->text; p != P; p = p->link) {
|
||||||
setarch(p);
|
|
||||||
a = p->as;
|
a = p->as;
|
||||||
if(seenthumb && a == ABL){
|
|
||||||
// if((s = p->to.sym) != S && (s1 = curtext->from.sym) != S)
|
|
||||||
// print("%s calls %s\n", s1->name, s->name);
|
|
||||||
if((s = p->to.sym) != S && s->thumb != cursym->thumb)
|
|
||||||
s->foreign = 1;
|
|
||||||
}
|
|
||||||
if((a == ABL || a == ABX || a == AB || a == ARET) &&
|
if((a == ABL || a == ABX || a == AB || a == ARET) &&
|
||||||
p->to.type != D_BRANCH && p->to.sym != S) {
|
p->to.type != D_BRANCH && p->to.sym != S) {
|
||||||
s = p->to.sym;
|
s = p->to.sym;
|
||||||
|
|
@ -254,19 +246,7 @@ patch(void)
|
||||||
|
|
||||||
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
||||||
for(p = cursym->text; p != P; p = p->link) {
|
for(p = cursym->text; p != P; p = p->link) {
|
||||||
setarch(p);
|
|
||||||
a = p->as;
|
a = p->as;
|
||||||
if(seenthumb && a == ABL) {
|
|
||||||
#ifdef CALLEEBX
|
|
||||||
if(0)
|
|
||||||
{}
|
|
||||||
#else
|
|
||||||
if((s = p->to.sym) != S && (s->foreign || s->fnptr))
|
|
||||||
p->as = ABX;
|
|
||||||
#endif
|
|
||||||
else if(p->to.type == D_OREG)
|
|
||||||
p->as = ABX;
|
|
||||||
}
|
|
||||||
if(p->cond != P) {
|
if(p->cond != P) {
|
||||||
p->cond = brloop(p->cond);
|
p->cond = brloop(p->cond);
|
||||||
if(p->cond != P)
|
if(p->cond != P)
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ doprof1(void)
|
||||||
s = lookup("__mcount", 0);
|
s = lookup("__mcount", 0);
|
||||||
n = 1;
|
n = 1;
|
||||||
for(p = firstp->link; p != P; p = p->link) {
|
for(p = firstp->link; p != P; p = p->link) {
|
||||||
setarch(p);
|
|
||||||
if(p->as == ATEXT) {
|
if(p->as == ATEXT) {
|
||||||
q = prg();
|
q = prg();
|
||||||
q->line = p->line;
|
q->line = p->line;
|
||||||
|
|
@ -74,7 +73,7 @@ doprof1(void)
|
||||||
p->from.sym = s;
|
p->from.sym = s;
|
||||||
p->from.offset = n*4 + 4;
|
p->from.offset = n*4 + 4;
|
||||||
p->to.type = D_REG;
|
p->to.type = D_REG;
|
||||||
p->to.reg = thumb ? REGTMPT : REGTMP;
|
p->to.reg = REGTMP;
|
||||||
|
|
||||||
q = prg();
|
q = prg();
|
||||||
q->line = p->line;
|
q->line = p->line;
|
||||||
|
|
@ -86,7 +85,7 @@ doprof1(void)
|
||||||
p->from.type = D_CONST;
|
p->from.type = D_CONST;
|
||||||
p->from.offset = 1;
|
p->from.offset = 1;
|
||||||
p->to.type = D_REG;
|
p->to.type = D_REG;
|
||||||
p->to.reg = thumb ? REGTMPT : REGTMP;
|
p->to.reg = REGTMP;
|
||||||
|
|
||||||
q = prg();
|
q = prg();
|
||||||
q->line = p->line;
|
q->line = p->line;
|
||||||
|
|
@ -96,7 +95,7 @@ doprof1(void)
|
||||||
p = q;
|
p = q;
|
||||||
p->as = AMOVW;
|
p->as = AMOVW;
|
||||||
p->from.type = D_REG;
|
p->from.type = D_REG;
|
||||||
p->from.reg = thumb ? REGTMPT : REGTMP;
|
p->from.reg = REGTMP;
|
||||||
p->to.type = D_OREG;
|
p->to.type = D_OREG;
|
||||||
p->to.name = D_EXTERN;
|
p->to.name = D_EXTERN;
|
||||||
p->to.sym = s;
|
p->to.sym = s;
|
||||||
|
|
@ -143,7 +142,6 @@ doprof2(void)
|
||||||
ps4 = P;
|
ps4 = P;
|
||||||
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
||||||
p = cursym->text;
|
p = cursym->text;
|
||||||
setarch(p);
|
|
||||||
if(cursym == s2) {
|
if(cursym == s2) {
|
||||||
ps2 = p;
|
ps2 = p;
|
||||||
p->reg = 1;
|
p->reg = 1;
|
||||||
|
|
@ -155,7 +153,6 @@ doprof2(void)
|
||||||
}
|
}
|
||||||
for(cursym = textp; cursym != nil; cursym = cursym->next)
|
for(cursym = textp; cursym != nil; cursym = cursym->next)
|
||||||
for(p = cursym->text; p != P; p = p->link) {
|
for(p = cursym->text; p != P; p = p->link) {
|
||||||
setarch(p);
|
|
||||||
if(p->as == ATEXT) {
|
if(p->as == ATEXT) {
|
||||||
if(p->reg & NOPROF) {
|
if(p->reg & NOPROF) {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
|
|
||||||
|
|
@ -49,86 +49,6 @@ isbranch(Prog *p)
|
||||||
return (as >= ABEQ && as <= ABLE) || as == AB || as == ABL || as == ABX;
|
return (as >= ABEQ && as <= ABLE) || as == AB || as == ABL || as == ABX;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
ispad(Prog *p)
|
|
||||||
{
|
|
||||||
if(p->as != AMOVW)
|
|
||||||
return 0;
|
|
||||||
if(p->from.type != D_REG || p->from.reg != REGTMP)
|
|
||||||
return 0;
|
|
||||||
if(p->to.type != D_REG || p->to.reg != REGTMP)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fninc(Sym *s)
|
|
||||||
{
|
|
||||||
if(thumb){
|
|
||||||
if(s->thumb){
|
|
||||||
if(s->foreign)
|
|
||||||
return 8;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(s->foreign)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
diag("T A !foreign in fninc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(s->thumb){
|
|
||||||
if(s->foreign)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
diag("A T !foreign in fninc");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(s->foreign)
|
|
||||||
return 4;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fnpinc(Sym *s)
|
|
||||||
{
|
|
||||||
if(!s->fnptr){ // a simplified case BX O(R) -> BL O(R)
|
|
||||||
if(!debug['f'])
|
|
||||||
diag("fnptr == 0 in fnpinc");
|
|
||||||
if(s->foreign)
|
|
||||||
diag("bad usage in fnpinc %s %d %d", s->name, s->foreign, s->thumb);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* 0, 1, 2, 3 squared */
|
|
||||||
if(s->thumb)
|
|
||||||
return s->foreign ? 9 : 1;
|
|
||||||
else
|
|
||||||
return s->foreign ? 4 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Prog *
|
|
||||||
pad(Prog *p, int pc)
|
|
||||||
{
|
|
||||||
Prog *q;
|
|
||||||
|
|
||||||
q = prg();
|
|
||||||
q->as = AMOVW;
|
|
||||||
q->line = p->line;
|
|
||||||
q->from.type = D_REG;
|
|
||||||
q->from.reg = REGTMP;
|
|
||||||
q->to.type = D_REG;
|
|
||||||
q->to.reg = REGTMP;
|
|
||||||
q->pc = pc;
|
|
||||||
q->link = p->link;
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
scan(Prog *op, Prog *p, int c)
|
scan(Prog *op, Prog *p, int c)
|
||||||
{
|
{
|
||||||
|
|
@ -182,7 +102,6 @@ span(void)
|
||||||
otxt = c;
|
otxt = c;
|
||||||
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
||||||
p = cursym->text;
|
p = cursym->text;
|
||||||
setarch(p);
|
|
||||||
p->pc = c;
|
p->pc = c;
|
||||||
cursym->value = c;
|
cursym->value = c;
|
||||||
|
|
||||||
|
|
@ -193,19 +112,14 @@ span(void)
|
||||||
if(c-otxt >= 1L<<17)
|
if(c-otxt >= 1L<<17)
|
||||||
bflag = 1;
|
bflag = 1;
|
||||||
otxt = c;
|
otxt = c;
|
||||||
if(thumb && blitrl)
|
|
||||||
pool.extra += brextra(p);
|
|
||||||
|
|
||||||
for(op = p, p = p->link; p != P; op = p, p = p->link) {
|
for(op = p, p = p->link; p != P; op = p, p = p->link) {
|
||||||
curp = p;
|
curp = p;
|
||||||
setarch(p);
|
|
||||||
p->pc = c;
|
p->pc = c;
|
||||||
o = oplook(p);
|
o = oplook(p);
|
||||||
m = o->size;
|
m = o->size;
|
||||||
// must check literal pool here in case p generates many instructions
|
// must check literal pool here in case p generates many instructions
|
||||||
if(blitrl){
|
if(blitrl){
|
||||||
if(thumb && isbranch(p))
|
|
||||||
pool.extra += brextra(p);
|
|
||||||
if(checkpool(op, p->as == ACASE ? casesz(p) : m))
|
if(checkpool(op, p->as == ACASE ? casesz(p) : m))
|
||||||
c = p->pc = scan(op, p, c);
|
c = p->pc = scan(op, p, c);
|
||||||
}
|
}
|
||||||
|
|
@ -230,8 +144,6 @@ span(void)
|
||||||
c += m;
|
c += m;
|
||||||
}
|
}
|
||||||
if(blitrl){
|
if(blitrl){
|
||||||
if(thumb && isbranch(op))
|
|
||||||
pool.extra += brextra(op);
|
|
||||||
if(checkpool(op, 0))
|
if(checkpool(op, 0))
|
||||||
c = scan(op, P, c);
|
c = scan(op, P, c);
|
||||||
}
|
}
|
||||||
|
|
@ -253,10 +165,7 @@ span(void)
|
||||||
cursym->value = c;
|
cursym->value = c;
|
||||||
for(p = cursym->text; p != P; p = p->link) {
|
for(p = cursym->text; p != P; p = p->link) {
|
||||||
curp = p;
|
curp = p;
|
||||||
setarch(p);
|
|
||||||
p->pc = c;
|
p->pc = c;
|
||||||
if(thumb && isbranch(p))
|
|
||||||
nocache(p);
|
|
||||||
o = oplook(p);
|
o = oplook(p);
|
||||||
/* very large branches
|
/* very large branches
|
||||||
if(o->type == 6 && p->cond) {
|
if(o->type == 6 && p->cond) {
|
||||||
|
|
@ -298,74 +207,6 @@ span(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(seenthumb){ // branch resolution
|
|
||||||
int passes = 0;
|
|
||||||
int lastc = 0;
|
|
||||||
int again;
|
|
||||||
Prog *oop;
|
|
||||||
|
|
||||||
loop:
|
|
||||||
passes++;
|
|
||||||
if(passes > 100){
|
|
||||||
diag("span looping !");
|
|
||||||
errorexit();
|
|
||||||
}
|
|
||||||
c = INITTEXT;
|
|
||||||
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) {
|
|
||||||
curp = p;
|
|
||||||
setarch(p);
|
|
||||||
if(p->pc != c)
|
|
||||||
again = 1;
|
|
||||||
p->pc = c;
|
|
||||||
if(thumb && isbranch(p))
|
|
||||||
nocache(p);
|
|
||||||
o = oplook(p);
|
|
||||||
m = o->size;
|
|
||||||
if(passes == 1 && thumb && isbranch(p)){ // start conservative so unneeded alignment is not added
|
|
||||||
if(p->as == ABL)
|
|
||||||
m = 4;
|
|
||||||
else
|
|
||||||
m = 2;
|
|
||||||
p->align = 0;
|
|
||||||
}
|
|
||||||
if(p->align){
|
|
||||||
if((p->align == 4 && (c&3)) || (p->align == 2 && !(c&3))){
|
|
||||||
if(ispad(op)){
|
|
||||||
oop->link = p;
|
|
||||||
op = oop;
|
|
||||||
c -= 2;
|
|
||||||
p->pc = c;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
op->link = pad(op, c);
|
|
||||||
op = op->link;
|
|
||||||
c += 2;
|
|
||||||
p->pc = c;
|
|
||||||
}
|
|
||||||
again = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(m == 0) {
|
|
||||||
if(p->as == ATEXT) {
|
|
||||||
autosize = p->to.offset + 4;
|
|
||||||
if(p->from.sym != S)
|
|
||||||
p->from.sym->value = c;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c += m;
|
|
||||||
}
|
|
||||||
cursym->size = c - cursym->value;
|
|
||||||
}
|
|
||||||
if(c != lastc || again){
|
|
||||||
lastc = c;
|
|
||||||
goto loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c = rnd(c, 8);
|
c = rnd(c, 8);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -378,7 +219,6 @@ span(void)
|
||||||
*/
|
*/
|
||||||
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
for(cursym = textp; cursym != nil; cursym = cursym->next) {
|
||||||
p = cursym->text;
|
p = cursym->text;
|
||||||
setarch(p);
|
|
||||||
autosize = p->to.offset + 4;
|
autosize = p->to.offset + 4;
|
||||||
symgrow(cursym, cursym->size);
|
symgrow(cursym, cursym->size);
|
||||||
|
|
||||||
|
|
@ -412,13 +252,6 @@ span(void)
|
||||||
int
|
int
|
||||||
checkpool(Prog *p, int sz)
|
checkpool(Prog *p, int sz)
|
||||||
{
|
{
|
||||||
if(thumb){
|
|
||||||
if(pool.size >= 0x3fc || (p->pc+sz+pool.extra+2+2)+(pool.size-4)-pool.start-4 >= 0x3fc)
|
|
||||||
return flushpool(p, 1, 0);
|
|
||||||
else if(p->link == P)
|
|
||||||
return flushpool(p, 2, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(pool.size >= 0xffc || immaddr((p->pc+sz+4)+4+pool.size - pool.start+8) == 0)
|
if(pool.size >= 0xffc || immaddr((p->pc+sz+4)+4+pool.size - pool.start+8) == 0)
|
||||||
return flushpool(p, 1, 0);
|
return flushpool(p, 1, 0);
|
||||||
else if(p->link == P)
|
else if(p->link == P)
|
||||||
|
|
@ -441,7 +274,7 @@ flushpool(Prog *p, int skip, int force)
|
||||||
q->link = blitrl;
|
q->link = blitrl;
|
||||||
blitrl = q;
|
blitrl = q;
|
||||||
}
|
}
|
||||||
else if(!force && (p->pc+pool.size-pool.start < (thumb ? 0x3fc+4-pool.extra : 2048)))
|
else if(!force && (p->pc+pool.size-pool.start < 2048))
|
||||||
return 0;
|
return 0;
|
||||||
elitrl->link = p->link;
|
elitrl->link = p->link;
|
||||||
p->link = blitrl;
|
p->link = blitrl;
|
||||||
|
|
@ -461,10 +294,7 @@ addpool(Prog *p, Adr *a)
|
||||||
Prog *q, t;
|
Prog *q, t;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if(thumb)
|
c = aclass(a);
|
||||||
c = thumbaclass(a, p);
|
|
||||||
else
|
|
||||||
c = aclass(a);
|
|
||||||
|
|
||||||
t = zprg;
|
t = zprg;
|
||||||
t.as = AWORD;
|
t.as = AWORD;
|
||||||
|
|
@ -480,12 +310,10 @@ addpool(Prog *p, Adr *a)
|
||||||
case C_FOREG:
|
case C_FOREG:
|
||||||
case C_SOREG:
|
case C_SOREG:
|
||||||
case C_HOREG:
|
case C_HOREG:
|
||||||
case C_GOREG:
|
|
||||||
case C_FAUTO:
|
case C_FAUTO:
|
||||||
case C_SAUTO:
|
case C_SAUTO:
|
||||||
case C_LAUTO:
|
case C_LAUTO:
|
||||||
case C_LACON:
|
case C_LACON:
|
||||||
case C_GACON:
|
|
||||||
t.to.type = D_CONST;
|
t.to.type = D_CONST;
|
||||||
t.to.offset = instoffset;
|
t.to.offset = instoffset;
|
||||||
break;
|
break;
|
||||||
|
|
@ -591,16 +419,6 @@ symaddr(Sym *s)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case STEXT:
|
case STEXT:
|
||||||
/* TODO(rsc): what is this for?
|
|
||||||
#ifdef CALLEEBX
|
|
||||||
v += fnpinc(s);
|
|
||||||
#else
|
|
||||||
if(s->thumb)
|
|
||||||
v++; // T bit
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SELFDATA:
|
case SELFDATA:
|
||||||
case SRODATA:
|
case SRODATA:
|
||||||
case SDATA:
|
case SDATA:
|
||||||
|
|
@ -768,35 +586,19 @@ oplook(Prog *p)
|
||||||
int a1, a2, a3, r;
|
int a1, a2, a3, r;
|
||||||
char *c1, *c3;
|
char *c1, *c3;
|
||||||
Optab *o, *e;
|
Optab *o, *e;
|
||||||
Optab *otab;
|
|
||||||
Oprang *orange;
|
|
||||||
|
|
||||||
if(thumb){
|
|
||||||
otab = thumboptab;
|
|
||||||
orange = thumboprange;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
otab = optab;
|
|
||||||
orange = oprange;
|
|
||||||
}
|
|
||||||
a1 = p->optab;
|
a1 = p->optab;
|
||||||
if(a1)
|
if(a1)
|
||||||
return otab+(a1-1);
|
return optab+(a1-1);
|
||||||
a1 = p->from.class;
|
a1 = p->from.class;
|
||||||
if(a1 == 0) {
|
if(a1 == 0) {
|
||||||
if(thumb)
|
a1 = aclass(&p->from) + 1;
|
||||||
a1 = thumbaclass(&p->from, p) + 1;
|
|
||||||
else
|
|
||||||
a1 = aclass(&p->from) + 1;
|
|
||||||
p->from.class = a1;
|
p->from.class = a1;
|
||||||
}
|
}
|
||||||
a1--;
|
a1--;
|
||||||
a3 = p->to.class;
|
a3 = p->to.class;
|
||||||
if(a3 == 0) {
|
if(a3 == 0) {
|
||||||
if(thumb)
|
a3 = aclass(&p->to) + 1;
|
||||||
a3 = thumbaclass(&p->to, p) + 1;
|
|
||||||
else
|
|
||||||
a3 = aclass(&p->to) + 1;
|
|
||||||
p->to.class = a3;
|
p->to.class = a3;
|
||||||
}
|
}
|
||||||
a3--;
|
a3--;
|
||||||
|
|
@ -804,35 +606,35 @@ oplook(Prog *p)
|
||||||
if(p->reg != NREG)
|
if(p->reg != NREG)
|
||||||
a2 = C_REG;
|
a2 = C_REG;
|
||||||
r = p->as;
|
r = p->as;
|
||||||
o = orange[r].start;
|
o = oprange[r].start;
|
||||||
if(o == 0) {
|
if(o == 0) {
|
||||||
a1 = opcross[repop[r]][a1][a2][a3];
|
a1 = opcross[repop[r]][a1][a2][a3];
|
||||||
if(a1) {
|
if(a1) {
|
||||||
p->optab = a1+1;
|
p->optab = a1+1;
|
||||||
return otab+a1;
|
return optab+a1;
|
||||||
}
|
}
|
||||||
o = orange[r].stop; /* just generate an error */
|
o = oprange[r].stop; /* just generate an error */
|
||||||
}
|
}
|
||||||
if(debug['O']) {
|
if(debug['O']) {
|
||||||
print("oplook %A %O %O %O\n",
|
print("oplook %A %O %O %O\n",
|
||||||
(int)p->as, a1, a2, a3);
|
(int)p->as, a1, a2, a3);
|
||||||
print(" %d %d\n", p->from.type, p->to.type);
|
print(" %d %d\n", p->from.type, p->to.type);
|
||||||
}
|
}
|
||||||
e = orange[r].stop;
|
e = oprange[r].stop;
|
||||||
c1 = xcmp[a1];
|
c1 = xcmp[a1];
|
||||||
c3 = xcmp[a3];
|
c3 = xcmp[a3];
|
||||||
for(; o<e; o++)
|
for(; o<e; o++)
|
||||||
if(o->a2 == a2)
|
if(o->a2 == a2)
|
||||||
if(c1[o->a1])
|
if(c1[o->a1])
|
||||||
if(c3[o->a3]) {
|
if(c3[o->a3]) {
|
||||||
p->optab = (o-otab)+1;
|
p->optab = (o-optab)+1;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
diag("illegal combination %A %O %O %O, %d %d",
|
diag("illegal combination %A %O %O %O, %d %d",
|
||||||
p->as, a1, a2, a3, p->from.type, p->to.type);
|
p->as, a1, a2, a3, p->from.type, p->to.type);
|
||||||
prasm(p);
|
prasm(p);
|
||||||
if(o == 0)
|
if(o == 0)
|
||||||
o = otab;
|
o = optab;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -883,9 +685,6 @@ cmp(int a, int b)
|
||||||
if(b == C_SBRA)
|
if(b == C_SBRA)
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case C_GBRA:
|
|
||||||
if(b == C_SBRA || b == C_LBRA)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
case C_HREG:
|
case C_HREG:
|
||||||
return cmp(C_SP, b) || cmp(C_PC, b);
|
return cmp(C_SP, b) || cmp(C_PC, b);
|
||||||
|
|
@ -903,9 +702,6 @@ ocmp(const void *a1, const void *a2)
|
||||||
p1 = (Optab*)a1;
|
p1 = (Optab*)a1;
|
||||||
p2 = (Optab*)a2;
|
p2 = (Optab*)a2;
|
||||||
n = p1->as - p2->as;
|
n = p1->as - p2->as;
|
||||||
if(n)
|
|
||||||
return n;
|
|
||||||
n = (p2->flag&V4) - (p1->flag&V4); /* architecture version */
|
|
||||||
if(n)
|
if(n)
|
||||||
return n;
|
return n;
|
||||||
n = p1->a1 - p2->a1;
|
n = p1->a1 - p2->a1;
|
||||||
|
|
@ -925,15 +721,11 @@ buildop(void)
|
||||||
{
|
{
|
||||||
int i, n, r;
|
int i, n, r;
|
||||||
|
|
||||||
armv4 = 1;
|
|
||||||
for(i=0; i<C_GOK; i++)
|
for(i=0; i<C_GOK; i++)
|
||||||
for(n=0; n<C_GOK; n++)
|
for(n=0; n<C_GOK; n++)
|
||||||
xcmp[i][n] = cmp(n, i);
|
xcmp[i][n] = cmp(n, i);
|
||||||
for(n=0; optab[n].as != AXXX; n++)
|
for(n=0; optab[n].as != AXXX; n++)
|
||||||
if((optab[n].flag & V4) && !armv4) {
|
;
|
||||||
optab[n].as = AXXX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
qsort(optab, n, sizeof(optab[0]), ocmp);
|
qsort(optab, n, sizeof(optab[0]), ocmp);
|
||||||
for(i=0; i<n; i++) {
|
for(i=0; i<n; i++) {
|
||||||
r = optab[i].as;
|
r = optab[i].as;
|
||||||
|
|
|
||||||
1658
src/cmd/5l/thumb.c
1658
src/cmd/5l/thumb.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue