mirror of
https://github.com/golang/go
synced 2024-11-18 17:54:57 -07:00
liblink: define fixed A-numbers for common instructions
This makes names like ANOP, ATEXT, AGLOBL, ACALL, AJMP, ARET available for use by architecture-independent processing passes. On arm and ppc64, the alternate names are now aliases for the official ones (ABL for ACALL, AB or ABR for AJMP, ARETURN for ARET). Change-Id: Id027771243795af2b3745199c645b6e1bedd7d18 Reviewed-on: https://go-review.googlesource.com/3577 Reviewed-by: Aram Hăvărneanu <aram@mgk.ro> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
3ac37c72ae
commit
2e5b065ac2
@ -249,6 +249,35 @@ struct Prog
|
|||||||
|
|
||||||
extern Prog zprog; // zeroed Prog
|
extern Prog zprog; // zeroed Prog
|
||||||
|
|
||||||
|
// Prog.as opcodes.
|
||||||
|
// These are the portable opcodes, common to all architectures.
|
||||||
|
// Each architecture defines many more arch-specific opcodes,
|
||||||
|
// with values starting at A_ARCHSPECIFIC.
|
||||||
|
enum {
|
||||||
|
AXXX = 0,
|
||||||
|
|
||||||
|
ACALL,
|
||||||
|
ACHECKNIL,
|
||||||
|
ADATA,
|
||||||
|
ADUFFCOPY,
|
||||||
|
ADUFFZERO,
|
||||||
|
AEND,
|
||||||
|
AFUNCDATA,
|
||||||
|
AGLOBL,
|
||||||
|
AJMP,
|
||||||
|
ANOP,
|
||||||
|
APCDATA,
|
||||||
|
ARET,
|
||||||
|
ATEXT,
|
||||||
|
ATYPE,
|
||||||
|
AUNDEF,
|
||||||
|
AUSEFIELD,
|
||||||
|
AVARDEF,
|
||||||
|
AVARKILL,
|
||||||
|
|
||||||
|
A_ARCHSPECIFIC, // first architecture-specific opcode value
|
||||||
|
};
|
||||||
|
|
||||||
// prevent incompatible type signatures between liblink and 8l on Plan 9
|
// prevent incompatible type signatures between liblink and 8l on Plan 9
|
||||||
#pragma incomplete struct Section
|
#pragma incomplete struct Section
|
||||||
|
|
||||||
@ -599,26 +628,11 @@ struct LinkArch
|
|||||||
void (*preprocess)(Link*, LSym*);
|
void (*preprocess)(Link*, LSym*);
|
||||||
void (*assemble)(Link*, LSym*);
|
void (*assemble)(Link*, LSym*);
|
||||||
void (*follow)(Link*, LSym*);
|
void (*follow)(Link*, LSym*);
|
||||||
int (*iscall)(Prog*);
|
|
||||||
int (*isdata)(Prog*);
|
|
||||||
void (*progedit)(Link*, Prog*);
|
void (*progedit)(Link*, Prog*);
|
||||||
|
|
||||||
int minlc;
|
int minlc;
|
||||||
int ptrsize;
|
int ptrsize;
|
||||||
int regsize;
|
int regsize;
|
||||||
|
|
||||||
int ACALL;
|
|
||||||
int ADATA;
|
|
||||||
int AEND;
|
|
||||||
int AFUNCDATA;
|
|
||||||
int AGLOBL;
|
|
||||||
int AJMP;
|
|
||||||
int ANOP;
|
|
||||||
int APCDATA;
|
|
||||||
int ARET;
|
|
||||||
int ATEXT;
|
|
||||||
int ATYPE;
|
|
||||||
int AUSEFIELD;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* executable header types */
|
/* executable header types */
|
||||||
|
@ -46,22 +46,6 @@ main(int argc, char **argv)
|
|||||||
arch.thestring = thestring;
|
arch.thestring = thestring;
|
||||||
arch.thelinkarch = thelinkarch;
|
arch.thelinkarch = thelinkarch;
|
||||||
arch.typedefs = typedefs;
|
arch.typedefs = typedefs;
|
||||||
arch.ACALL = ABL;
|
|
||||||
arch.ACHECKNIL = ACHECKNIL;
|
|
||||||
arch.ADATA = ADATA;
|
|
||||||
arch.AFUNCDATA = AFUNCDATA;
|
|
||||||
arch.AGLOBL = AGLOBL;
|
|
||||||
arch.AJMP = AB;
|
|
||||||
arch.ANAME = ANAME;
|
|
||||||
arch.ANOP = ANOP;
|
|
||||||
arch.APCDATA = APCDATA;
|
|
||||||
arch.ARET = ARET;
|
|
||||||
arch.ASIGNAME = ASIGNAME;
|
|
||||||
arch.ATEXT = ATEXT;
|
|
||||||
arch.ATYPE = ATYPE;
|
|
||||||
arch.AUNDEF = AUNDEF;
|
|
||||||
arch.AVARDEF = AVARDEF;
|
|
||||||
arch.AVARKILL = AVARKILL;
|
|
||||||
arch.MAXWIDTH = MAXWIDTH;
|
arch.MAXWIDTH = MAXWIDTH;
|
||||||
arch.afunclit = afunclit;
|
arch.afunclit = afunclit;
|
||||||
arch.anyregalloc = anyregalloc;
|
arch.anyregalloc = anyregalloc;
|
||||||
|
@ -177,10 +177,3 @@ int BtoF(uint32);
|
|||||||
* prog.c
|
* prog.c
|
||||||
*/
|
*/
|
||||||
void proginfo(ProgInfo*, Prog*);
|
void proginfo(ProgInfo*, Prog*);
|
||||||
|
|
||||||
// To allow use of AJMP and ACALL in ../gc/popt.c.
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
AJMP = AB,
|
|
||||||
ACALL = ABL,
|
|
||||||
};
|
|
||||||
|
@ -1385,9 +1385,6 @@ predicable(Prog *p)
|
|||||||
case AXXX:
|
case AXXX:
|
||||||
case ADATA:
|
case ADATA:
|
||||||
case AGLOBL:
|
case AGLOBL:
|
||||||
case AHISTORY:
|
|
||||||
case ANAME:
|
|
||||||
case ASIGNAME:
|
|
||||||
case ATEXT:
|
case ATEXT:
|
||||||
case AWORD:
|
case AWORD:
|
||||||
case ABCASE:
|
case ABCASE:
|
||||||
|
@ -158,9 +158,7 @@ enum
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
AXXX,
|
AAND = A_ARCHSPECIFIC,
|
||||||
|
|
||||||
AAND,
|
|
||||||
AEOR,
|
AEOR,
|
||||||
ASUB,
|
ASUB,
|
||||||
ARSB,
|
ARSB,
|
||||||
@ -177,9 +175,6 @@ enum
|
|||||||
|
|
||||||
AMVN,
|
AMVN,
|
||||||
|
|
||||||
AB,
|
|
||||||
ABL,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not reorder or fragment the conditional branch
|
* Do not reorder or fragment the conditional branch
|
||||||
* opcodes, or the predication code will break
|
* opcodes, or the predication code will break
|
||||||
@ -246,24 +241,14 @@ enum
|
|||||||
ASWPBU,
|
ASWPBU,
|
||||||
ASWPW,
|
ASWPW,
|
||||||
|
|
||||||
ANOP,
|
|
||||||
ARFE,
|
ARFE,
|
||||||
ASWI,
|
ASWI,
|
||||||
AMULA,
|
AMULA,
|
||||||
|
|
||||||
ADATA,
|
|
||||||
AGLOBL,
|
|
||||||
AHISTORY,
|
|
||||||
ANAME,
|
|
||||||
ARET,
|
|
||||||
ATEXT,
|
|
||||||
AWORD,
|
AWORD,
|
||||||
ADYNT_,
|
|
||||||
AINIT_,
|
|
||||||
ABCASE,
|
ABCASE,
|
||||||
ACASE,
|
ACASE,
|
||||||
|
|
||||||
AEND,
|
|
||||||
|
|
||||||
AMULL,
|
AMULL,
|
||||||
AMULAL,
|
AMULAL,
|
||||||
@ -274,7 +259,6 @@ enum
|
|||||||
ABXRET,
|
ABXRET,
|
||||||
ADWORD,
|
ADWORD,
|
||||||
|
|
||||||
ASIGNAME,
|
|
||||||
|
|
||||||
ALDREX,
|
ALDREX,
|
||||||
ASTREX,
|
ASTREX,
|
||||||
@ -284,7 +268,6 @@ enum
|
|||||||
|
|
||||||
APLD,
|
APLD,
|
||||||
|
|
||||||
AUNDEF,
|
|
||||||
|
|
||||||
ACLZ,
|
ACLZ,
|
||||||
|
|
||||||
@ -293,21 +276,16 @@ enum
|
|||||||
AMULAWT,
|
AMULAWT,
|
||||||
AMULAWB,
|
AMULAWB,
|
||||||
|
|
||||||
AUSEFIELD,
|
|
||||||
ATYPE,
|
|
||||||
AFUNCDATA,
|
|
||||||
APCDATA,
|
|
||||||
ACHECKNIL,
|
|
||||||
AVARDEF,
|
|
||||||
AVARKILL,
|
|
||||||
ADUFFCOPY,
|
|
||||||
ADUFFZERO,
|
|
||||||
ADATABUNDLE,
|
ADATABUNDLE,
|
||||||
ADATABUNDLEEND,
|
ADATABUNDLEEND,
|
||||||
|
|
||||||
AMRC, // MRC/MCR
|
AMRC, // MRC/MCR
|
||||||
|
|
||||||
ALAST,
|
ALAST,
|
||||||
|
|
||||||
|
// aliases
|
||||||
|
AB = AJMP,
|
||||||
|
ABL = ACALL,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* scond byte */
|
/* scond byte */
|
||||||
|
@ -69,22 +69,6 @@ main(int argc, char **argv)
|
|||||||
arch.thestring = thestring;
|
arch.thestring = thestring;
|
||||||
arch.thelinkarch = thelinkarch;
|
arch.thelinkarch = thelinkarch;
|
||||||
arch.typedefs = typedefs;
|
arch.typedefs = typedefs;
|
||||||
arch.ACALL = ACALL;
|
|
||||||
arch.ACHECKNIL = ACHECKNIL;
|
|
||||||
arch.ADATA = ADATA;
|
|
||||||
arch.AFUNCDATA = AFUNCDATA;
|
|
||||||
arch.AGLOBL = AGLOBL;
|
|
||||||
arch.AJMP = AJMP;
|
|
||||||
arch.ANAME = ANAME;
|
|
||||||
arch.ANOP = ANOP;
|
|
||||||
arch.APCDATA = APCDATA;
|
|
||||||
arch.ARET = ARET;
|
|
||||||
arch.ASIGNAME = ASIGNAME;
|
|
||||||
arch.ATEXT = ATEXT;
|
|
||||||
arch.ATYPE = ATYPE;
|
|
||||||
arch.AUNDEF = AUNDEF;
|
|
||||||
arch.AVARDEF = AVARDEF;
|
|
||||||
arch.AVARKILL = AVARKILL;
|
|
||||||
arch.MAXWIDTH = MAXWIDTH;
|
arch.MAXWIDTH = MAXWIDTH;
|
||||||
arch.afunclit = afunclit;
|
arch.afunclit = afunclit;
|
||||||
arch.anyregalloc = anyregalloc;
|
arch.anyregalloc = anyregalloc;
|
||||||
|
@ -38,8 +38,7 @@
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
AXXX,
|
AAAA = A_ARCHSPECIFIC,
|
||||||
AAAA,
|
|
||||||
AAAD,
|
AAAD,
|
||||||
AAAM,
|
AAAM,
|
||||||
AAAS,
|
AAAS,
|
||||||
@ -69,7 +68,6 @@ enum
|
|||||||
ABTSL,
|
ABTSL,
|
||||||
ABTSW,
|
ABTSW,
|
||||||
ABYTE,
|
ABYTE,
|
||||||
ACALL,
|
|
||||||
ACLC,
|
ACLC,
|
||||||
ACLD,
|
ACLD,
|
||||||
ACLI,
|
ACLI,
|
||||||
@ -83,7 +81,6 @@ enum
|
|||||||
ACMPSW,
|
ACMPSW,
|
||||||
ADAA,
|
ADAA,
|
||||||
ADAS,
|
ADAS,
|
||||||
ADATA,
|
|
||||||
ADECB,
|
ADECB,
|
||||||
ADECL,
|
ADECL,
|
||||||
ADECQ,
|
ADECQ,
|
||||||
@ -92,8 +89,6 @@ enum
|
|||||||
ADIVL,
|
ADIVL,
|
||||||
ADIVW,
|
ADIVW,
|
||||||
AENTER,
|
AENTER,
|
||||||
AGLOBL,
|
|
||||||
AHISTORY,
|
|
||||||
AHLT,
|
AHLT,
|
||||||
AIDIVB,
|
AIDIVB,
|
||||||
AIDIVL,
|
AIDIVL,
|
||||||
@ -126,7 +121,6 @@ enum
|
|||||||
AJLS,
|
AJLS,
|
||||||
AJLT,
|
AJLT,
|
||||||
AJMI,
|
AJMI,
|
||||||
AJMP,
|
|
||||||
AJNE,
|
AJNE,
|
||||||
AJOC,
|
AJOC,
|
||||||
AJOS,
|
AJOS,
|
||||||
@ -169,11 +163,9 @@ enum
|
|||||||
AMULB,
|
AMULB,
|
||||||
AMULL,
|
AMULL,
|
||||||
AMULW,
|
AMULW,
|
||||||
ANAME,
|
|
||||||
ANEGB,
|
ANEGB,
|
||||||
ANEGL,
|
ANEGL,
|
||||||
ANEGW,
|
ANEGW,
|
||||||
ANOP,
|
|
||||||
ANOTB,
|
ANOTB,
|
||||||
ANOTL,
|
ANOTL,
|
||||||
ANOTW,
|
ANOTW,
|
||||||
@ -207,7 +199,6 @@ enum
|
|||||||
ARCRW,
|
ARCRW,
|
||||||
AREP,
|
AREP,
|
||||||
AREPN,
|
AREPN,
|
||||||
ARET,
|
|
||||||
AROLB,
|
AROLB,
|
||||||
AROLL,
|
AROLL,
|
||||||
AROLW,
|
AROLW,
|
||||||
@ -264,7 +255,6 @@ enum
|
|||||||
ATESTB,
|
ATESTB,
|
||||||
ATESTL,
|
ATESTL,
|
||||||
ATESTW,
|
ATESTW,
|
||||||
ATEXT,
|
|
||||||
AVERR,
|
AVERR,
|
||||||
AVERW,
|
AVERW,
|
||||||
AWAIT,
|
AWAIT,
|
||||||
@ -385,12 +375,8 @@ enum
|
|||||||
AFYL2X,
|
AFYL2X,
|
||||||
AFYL2XP1,
|
AFYL2XP1,
|
||||||
|
|
||||||
AEND,
|
|
||||||
|
|
||||||
ADYNT_,
|
|
||||||
AINIT_,
|
|
||||||
|
|
||||||
ASIGNAME,
|
|
||||||
|
|
||||||
/* extra 32-bit operations */
|
/* extra 32-bit operations */
|
||||||
ACMPXCHGB,
|
ACMPXCHGB,
|
||||||
@ -744,7 +730,6 @@ enum
|
|||||||
ABSWAPL,
|
ABSWAPL,
|
||||||
ABSWAPQ,
|
ABSWAPQ,
|
||||||
|
|
||||||
AUNDEF,
|
|
||||||
|
|
||||||
AAESENC,
|
AAESENC,
|
||||||
AAESENCLAST,
|
AAESENCLAST,
|
||||||
@ -756,15 +741,6 @@ enum
|
|||||||
APSHUFD,
|
APSHUFD,
|
||||||
APCLMULQDQ,
|
APCLMULQDQ,
|
||||||
|
|
||||||
AUSEFIELD,
|
|
||||||
ATYPE,
|
|
||||||
AFUNCDATA,
|
|
||||||
APCDATA,
|
|
||||||
ACHECKNIL,
|
|
||||||
AVARDEF,
|
|
||||||
AVARKILL,
|
|
||||||
ADUFFCOPY,
|
|
||||||
ADUFFZERO,
|
|
||||||
|
|
||||||
ALAST
|
ALAST
|
||||||
};
|
};
|
||||||
|
@ -46,22 +46,6 @@ main(int argc, char **argv)
|
|||||||
arch.thestring = thestring;
|
arch.thestring = thestring;
|
||||||
arch.thelinkarch = thelinkarch;
|
arch.thelinkarch = thelinkarch;
|
||||||
arch.typedefs = typedefs;
|
arch.typedefs = typedefs;
|
||||||
arch.ACALL = ACALL;
|
|
||||||
arch.ACHECKNIL = ACHECKNIL;
|
|
||||||
arch.ADATA = ADATA;
|
|
||||||
arch.AFUNCDATA = AFUNCDATA;
|
|
||||||
arch.AGLOBL = AGLOBL;
|
|
||||||
arch.AJMP = AJMP;
|
|
||||||
arch.ANAME = ANAME;
|
|
||||||
arch.ANOP = ANOP;
|
|
||||||
arch.APCDATA = APCDATA;
|
|
||||||
arch.ARET = ARET;
|
|
||||||
arch.ASIGNAME = ASIGNAME;
|
|
||||||
arch.ATEXT = ATEXT;
|
|
||||||
arch.ATYPE = ATYPE;
|
|
||||||
arch.AUNDEF = AUNDEF;
|
|
||||||
arch.AVARDEF = AVARDEF;
|
|
||||||
arch.AVARKILL = AVARKILL;
|
|
||||||
arch.MAXWIDTH = MAXWIDTH;
|
arch.MAXWIDTH = MAXWIDTH;
|
||||||
arch.afunclit = afunclit;
|
arch.afunclit = afunclit;
|
||||||
arch.anyregalloc = anyregalloc;
|
arch.anyregalloc = anyregalloc;
|
||||||
|
@ -34,8 +34,7 @@
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
AXXX,
|
AAAA = A_ARCHSPECIFIC,
|
||||||
AAAA,
|
|
||||||
AAAD,
|
AAAD,
|
||||||
AAAM,
|
AAAM,
|
||||||
AAAS,
|
AAAS,
|
||||||
@ -65,7 +64,6 @@ enum
|
|||||||
ABTSL,
|
ABTSL,
|
||||||
ABTSW,
|
ABTSW,
|
||||||
ABYTE,
|
ABYTE,
|
||||||
ACALL,
|
|
||||||
ACLC,
|
ACLC,
|
||||||
ACLD,
|
ACLD,
|
||||||
ACLI,
|
ACLI,
|
||||||
@ -79,7 +77,6 @@ enum
|
|||||||
ACMPSW,
|
ACMPSW,
|
||||||
ADAA,
|
ADAA,
|
||||||
ADAS,
|
ADAS,
|
||||||
ADATA,
|
|
||||||
ADECB,
|
ADECB,
|
||||||
ADECL,
|
ADECL,
|
||||||
ADECW,
|
ADECW,
|
||||||
@ -87,8 +84,6 @@ enum
|
|||||||
ADIVL,
|
ADIVL,
|
||||||
ADIVW,
|
ADIVW,
|
||||||
AENTER,
|
AENTER,
|
||||||
AGLOBL,
|
|
||||||
AHISTORY,
|
|
||||||
AHLT,
|
AHLT,
|
||||||
AIDIVB,
|
AIDIVB,
|
||||||
AIDIVL,
|
AIDIVL,
|
||||||
@ -121,7 +116,6 @@ enum
|
|||||||
AJLS,
|
AJLS,
|
||||||
AJLT,
|
AJLT,
|
||||||
AJMI,
|
AJMI,
|
||||||
AJMP,
|
|
||||||
AJNE,
|
AJNE,
|
||||||
AJOC,
|
AJOC,
|
||||||
AJOS,
|
AJOS,
|
||||||
@ -161,11 +155,9 @@ enum
|
|||||||
AMULB,
|
AMULB,
|
||||||
AMULL,
|
AMULL,
|
||||||
AMULW,
|
AMULW,
|
||||||
ANAME,
|
|
||||||
ANEGB,
|
ANEGB,
|
||||||
ANEGL,
|
ANEGL,
|
||||||
ANEGW,
|
ANEGW,
|
||||||
ANOP,
|
|
||||||
ANOTB,
|
ANOTB,
|
||||||
ANOTL,
|
ANOTL,
|
||||||
ANOTW,
|
ANOTW,
|
||||||
@ -199,7 +191,6 @@ enum
|
|||||||
ARCRW,
|
ARCRW,
|
||||||
AREP,
|
AREP,
|
||||||
AREPN,
|
AREPN,
|
||||||
ARET,
|
|
||||||
AROLB,
|
AROLB,
|
||||||
AROLL,
|
AROLL,
|
||||||
AROLW,
|
AROLW,
|
||||||
@ -256,7 +247,6 @@ enum
|
|||||||
ATESTB,
|
ATESTB,
|
||||||
ATESTL,
|
ATESTL,
|
||||||
ATESTW,
|
ATESTW,
|
||||||
ATEXT,
|
|
||||||
AVERR,
|
AVERR,
|
||||||
AVERW,
|
AVERW,
|
||||||
AWAIT,
|
AWAIT,
|
||||||
@ -381,12 +371,8 @@ enum
|
|||||||
AFYL2X,
|
AFYL2X,
|
||||||
AFYL2XP1,
|
AFYL2XP1,
|
||||||
|
|
||||||
AEND,
|
|
||||||
|
|
||||||
ADYNT_,
|
|
||||||
AINIT_,
|
|
||||||
|
|
||||||
ASIGNAME,
|
|
||||||
|
|
||||||
ACMPXCHGB,
|
ACMPXCHGB,
|
||||||
ACMPXCHGL,
|
ACMPXCHGL,
|
||||||
@ -456,7 +442,6 @@ enum
|
|||||||
|
|
||||||
ABSWAPL,
|
ABSWAPL,
|
||||||
|
|
||||||
AUNDEF,
|
|
||||||
|
|
||||||
// SSE2
|
// SSE2
|
||||||
AADDPD,
|
AADDPD,
|
||||||
@ -576,15 +561,6 @@ enum
|
|||||||
APINSRD,
|
APINSRD,
|
||||||
APSHUFB,
|
APSHUFB,
|
||||||
|
|
||||||
AUSEFIELD,
|
|
||||||
ATYPE,
|
|
||||||
AFUNCDATA,
|
|
||||||
APCDATA,
|
|
||||||
ACHECKNIL,
|
|
||||||
AVARDEF,
|
|
||||||
AVARKILL,
|
|
||||||
ADUFFCOPY,
|
|
||||||
ADUFFZERO,
|
|
||||||
|
|
||||||
ALAST
|
ALAST
|
||||||
};
|
};
|
||||||
|
@ -53,22 +53,6 @@ main(int argc, char **argv)
|
|||||||
arch.thestring = thestring;
|
arch.thestring = thestring;
|
||||||
arch.thelinkarch = thelinkarch;
|
arch.thelinkarch = thelinkarch;
|
||||||
arch.typedefs = typedefs;
|
arch.typedefs = typedefs;
|
||||||
arch.ACALL = ABL;
|
|
||||||
arch.ACHECKNIL = ACHECKNIL;
|
|
||||||
arch.ADATA = ADATA;
|
|
||||||
arch.AFUNCDATA = AFUNCDATA;
|
|
||||||
arch.AGLOBL = AGLOBL;
|
|
||||||
arch.AJMP = ABR;
|
|
||||||
arch.ANAME = ANAME;
|
|
||||||
arch.ANOP = ANOP;
|
|
||||||
arch.APCDATA = APCDATA;
|
|
||||||
arch.ARET = ARETURN;
|
|
||||||
arch.ASIGNAME = ASIGNAME;
|
|
||||||
arch.ATEXT = ATEXT;
|
|
||||||
arch.ATYPE = ATYPE;
|
|
||||||
arch.AUNDEF = AUNDEF;
|
|
||||||
arch.AVARDEF = AVARDEF;
|
|
||||||
arch.AVARKILL = AVARKILL;
|
|
||||||
arch.MAXWIDTH = MAXWIDTH;
|
arch.MAXWIDTH = MAXWIDTH;
|
||||||
arch.afunclit = afunclit;
|
arch.afunclit = afunclit;
|
||||||
arch.anyregalloc = anyregalloc;
|
arch.anyregalloc = anyregalloc;
|
||||||
|
@ -180,11 +180,3 @@ enum {
|
|||||||
|
|
||||||
int as2variant(int);
|
int as2variant(int);
|
||||||
int variant2as(int, int);
|
int variant2as(int, int);
|
||||||
|
|
||||||
// To allow use of AJMP, ACALL, ARET in ../gc/popt.c.
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
AJMP = ABR,
|
|
||||||
ACALL = ABL,
|
|
||||||
ARET = ARETURN,
|
|
||||||
};
|
|
||||||
|
@ -293,8 +293,7 @@ enum
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
AXXX,
|
AADD = A_ARCHSPECIFIC,
|
||||||
AADD,
|
|
||||||
AADDCC,
|
AADDCC,
|
||||||
AADDV,
|
AADDV,
|
||||||
AADDVCC,
|
AADDVCC,
|
||||||
@ -323,11 +322,9 @@ enum
|
|||||||
ABEQ,
|
ABEQ,
|
||||||
ABGE,
|
ABGE,
|
||||||
ABGT,
|
ABGT,
|
||||||
ABL,
|
|
||||||
ABLE,
|
ABLE,
|
||||||
ABLT,
|
ABLT,
|
||||||
ABNE,
|
ABNE,
|
||||||
ABR,
|
|
||||||
ABVC,
|
ABVC,
|
||||||
ABVS,
|
ABVS,
|
||||||
ACMP,
|
ACMP,
|
||||||
@ -511,18 +508,7 @@ enum
|
|||||||
ATW,
|
ATW,
|
||||||
|
|
||||||
ASYSCALL,
|
ASYSCALL,
|
||||||
ADATA,
|
|
||||||
AGLOBL,
|
|
||||||
AHISTORY,
|
|
||||||
ANAME,
|
|
||||||
ANOP,
|
|
||||||
ARETURN,
|
|
||||||
ATEXT,
|
|
||||||
AWORD,
|
AWORD,
|
||||||
AEND,
|
|
||||||
ADYNT,
|
|
||||||
AINIT,
|
|
||||||
ASIGNAME,
|
|
||||||
|
|
||||||
ARFCI,
|
ARFCI,
|
||||||
|
|
||||||
@ -611,18 +597,12 @@ enum
|
|||||||
/* more 64-bit operations */
|
/* more 64-bit operations */
|
||||||
AHRFID,
|
AHRFID,
|
||||||
|
|
||||||
AUNDEF,
|
ALAST,
|
||||||
AUSEFIELD,
|
|
||||||
ATYPE,
|
|
||||||
AFUNCDATA,
|
|
||||||
APCDATA,
|
|
||||||
ACHECKNIL,
|
|
||||||
AVARDEF,
|
|
||||||
AVARKILL,
|
|
||||||
ADUFFCOPY,
|
|
||||||
ADUFFZERO,
|
|
||||||
|
|
||||||
ALAST
|
// aliases
|
||||||
|
ABR = AJMP,
|
||||||
|
ABL = ACALL,
|
||||||
|
ARETURN = ARET,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
14
src/cmd/dist/buildgc.go
vendored
14
src/cmd/dist/buildgc.go
vendored
@ -53,7 +53,7 @@ func gcopnames(dir, file string) {
|
|||||||
func mkanames(dir, file string) {
|
func mkanames(dir, file string) {
|
||||||
ch := file[len(file)-3]
|
ch := file[len(file)-3]
|
||||||
targ := pathf("%s/../cmd/%cl/%c.out.h", dir, ch, ch)
|
targ := pathf("%s/../cmd/%cl/%c.out.h", dir, ch, ch)
|
||||||
in := readfile(targ)
|
in := readfile(pathf("%s/../../include/link.h", dir)) + readfile(targ)
|
||||||
lines := splitlines(in)
|
lines := splitlines(in)
|
||||||
|
|
||||||
// Include link.h so that the extern declaration there is
|
// Include link.h so that the extern declaration there is
|
||||||
@ -69,10 +69,20 @@ func mkanames(dir, file string) {
|
|||||||
|
|
||||||
fmt.Fprintf(&out, "char* anames%c[] = {\n", ch)
|
fmt.Fprintf(&out, "char* anames%c[] = {\n", ch)
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
if strings.HasPrefix(line, "\tA") {
|
// Use all A names found in the headers,
|
||||||
|
// except don't use A_ARCHSPECIFIC (left to arch to define),
|
||||||
|
// and don't use any aliases (= A...),
|
||||||
|
// except do use the arch-defined alias for A_ARCHSPECIFIC.
|
||||||
|
if strings.Contains(line, ";") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(line, "\tA") && !strings.Contains(line, "\tA_") && (!strings.Contains(line, "= A") || strings.Contains(line, "= A_ARCHSPECIFIC")) {
|
||||||
if i := strings.Index(line, ","); i >= 0 {
|
if i := strings.Index(line, ","); i >= 0 {
|
||||||
line = line[:i]
|
line = line[:i]
|
||||||
}
|
}
|
||||||
|
if i := strings.Index(line, "="); i >= 0 {
|
||||||
|
line = line[:i]
|
||||||
|
}
|
||||||
if i := strings.Index(line, "\n"); i >= 0 {
|
if i := strings.Index(line, "\n"); i >= 0 {
|
||||||
line = line[:i]
|
line = line[:i]
|
||||||
}
|
}
|
||||||
|
@ -1658,22 +1658,6 @@ struct Arch
|
|||||||
LinkArch *thelinkarch;
|
LinkArch *thelinkarch;
|
||||||
Typedef *typedefs;
|
Typedef *typedefs;
|
||||||
|
|
||||||
int ACALL;
|
|
||||||
int ACHECKNIL;
|
|
||||||
int ADATA;
|
|
||||||
int AFUNCDATA;
|
|
||||||
int AGLOBL;
|
|
||||||
int AJMP;
|
|
||||||
int ANAME;
|
|
||||||
int ANOP;
|
|
||||||
int APCDATA;
|
|
||||||
int ARET;
|
|
||||||
int ASIGNAME;
|
|
||||||
int ATEXT;
|
|
||||||
int ATYPE;
|
|
||||||
int AUNDEF;
|
|
||||||
int AVARDEF;
|
|
||||||
int AVARKILL;
|
|
||||||
vlong MAXWIDTH;
|
vlong MAXWIDTH;
|
||||||
|
|
||||||
void (*afunclit)(Addr*, Node*);
|
void (*afunclit)(Addr*, Node*);
|
||||||
|
@ -30,7 +30,7 @@ makefuncdatasym(char *namefmt, int64 funcdatakind)
|
|||||||
pnod = newname(sym);
|
pnod = newname(sym);
|
||||||
pnod->class = PEXTERN;
|
pnod->class = PEXTERN;
|
||||||
nodconst(&nod, types[TINT32], funcdatakind);
|
nodconst(&nod, types[TINT32], funcdatakind);
|
||||||
arch.gins(arch.AFUNCDATA, &nod, pnod);
|
arch.gins(AFUNCDATA, &nod, pnod);
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,13 +110,13 @@ gvardefx(Node *n, int as)
|
|||||||
void
|
void
|
||||||
gvardef(Node *n)
|
gvardef(Node *n)
|
||||||
{
|
{
|
||||||
gvardefx(n, arch.AVARDEF);
|
gvardefx(n, AVARDEF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gvarkill(Node *n)
|
gvarkill(Node *n)
|
||||||
{
|
{
|
||||||
gvardefx(n, arch.AVARKILL);
|
gvardefx(n, AVARKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -125,10 +125,10 @@ removevardef(Prog *firstp)
|
|||||||
Prog *p;
|
Prog *p;
|
||||||
|
|
||||||
for(p = firstp; p != P; p = p->link) {
|
for(p = firstp; p != P; p = p->link) {
|
||||||
while(p->link != P && (p->link->as == arch.AVARDEF || p->link->as == arch.AVARKILL))
|
while(p->link != P && (p->link->as == AVARDEF || p->link->as == AVARKILL))
|
||||||
p->link = p->link->link;
|
p->link = p->link->link;
|
||||||
if(p->to.type == TYPE_BRANCH)
|
if(p->to.type == TYPE_BRANCH)
|
||||||
while(p->to.u.branch != P && (p->to.u.branch->as == arch.AVARDEF || p->to.u.branch->as == arch.AVARKILL))
|
while(p->to.u.branch != P && (p->to.u.branch->as == AVARDEF || p->to.u.branch->as == AVARKILL))
|
||||||
p->to.u.branch = p->to.u.branch->link;
|
p->to.u.branch = p->to.u.branch->link;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,7 +229,7 @@ compile(Node *fn)
|
|||||||
setlineno(curfn);
|
setlineno(curfn);
|
||||||
|
|
||||||
nodconst(&nod1, types[TINT32], 0);
|
nodconst(&nod1, types[TINT32], 0);
|
||||||
ptxt = arch.gins(arch.ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1);
|
ptxt = arch.gins(ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1);
|
||||||
if(fn->dupok)
|
if(fn->dupok)
|
||||||
ptxt->from3.offset |= DUPOK;
|
ptxt->from3.offset |= DUPOK;
|
||||||
if(fn->wrapper)
|
if(fn->wrapper)
|
||||||
@ -266,7 +266,7 @@ compile(Node *fn)
|
|||||||
case PPARAM:
|
case PPARAM:
|
||||||
case PPARAMOUT:
|
case PPARAMOUT:
|
||||||
nodconst(&nod1, types[TUINTPTR], l->n->type->width);
|
nodconst(&nod1, types[TUINTPTR], l->n->type->width);
|
||||||
p = arch.gins(arch.ATYPE, l->n, &nod1);
|
p = arch.gins(ATYPE, l->n, &nod1);
|
||||||
p->from.gotype = linksym(ngotype(l->n));
|
p->from.gotype = linksym(ngotype(l->n));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -297,7 +297,7 @@ compile(Node *fn)
|
|||||||
if(nerrors != 0)
|
if(nerrors != 0)
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
pc->as = arch.ARET; // overwrite AEND
|
pc->as = ARET; // overwrite AEND
|
||||||
pc->lineno = lineno;
|
pc->lineno = lineno;
|
||||||
|
|
||||||
fixjmp(ptxt);
|
fixjmp(ptxt);
|
||||||
@ -535,9 +535,9 @@ cgen_checknil(Node *n)
|
|||||||
if(((arch.thechar == '5' || arch.thechar == '9') && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) {
|
if(((arch.thechar == '5' || arch.thechar == '9') && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) {
|
||||||
arch.regalloc(®, types[tptr], n);
|
arch.regalloc(®, types[tptr], n);
|
||||||
arch.cgen(n, ®);
|
arch.cgen(n, ®);
|
||||||
arch.gins(arch.ACHECKNIL, ®, N);
|
arch.gins(ACHECKNIL, ®, N);
|
||||||
arch.regfree(®);
|
arch.regfree(®);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
arch.gins(arch.ACHECKNIL, n, N);
|
arch.gins(ACHECKNIL, n, N);
|
||||||
}
|
}
|
||||||
|
@ -371,7 +371,7 @@ iscall(Prog *prog, LSym *name)
|
|||||||
fatal("iscall: prog is nil");
|
fatal("iscall: prog is nil");
|
||||||
if(name == nil)
|
if(name == nil)
|
||||||
fatal("iscall: function name is nil");
|
fatal("iscall: function name is nil");
|
||||||
if(prog->as != arch.ACALL)
|
if(prog->as != ACALL)
|
||||||
return 0;
|
return 0;
|
||||||
return name == prog->to.sym;
|
return name == prog->to.sym;
|
||||||
}
|
}
|
||||||
@ -519,7 +519,7 @@ newcfg(Prog *firstp)
|
|||||||
p->to.u.branch->opt = newblock(p->to.u.branch);
|
p->to.u.branch->opt = newblock(p->to.u.branch);
|
||||||
arrayadd(cfg, &p->to.u.branch->opt);
|
arrayadd(cfg, &p->to.u.branch->opt);
|
||||||
}
|
}
|
||||||
if(p->as != arch.AJMP && p->link != nil && p->link->opt == nil) {
|
if(p->as != AJMP && p->link != nil && p->link->opt == nil) {
|
||||||
p->link->opt = newblock(p->link);
|
p->link->opt = newblock(p->link);
|
||||||
arrayadd(cfg, &p->link->opt);
|
arrayadd(cfg, &p->link->opt);
|
||||||
}
|
}
|
||||||
@ -544,7 +544,7 @@ newcfg(Prog *firstp)
|
|||||||
|
|
||||||
// Stop before an unreachable RET, to avoid creating
|
// Stop before an unreachable RET, to avoid creating
|
||||||
// unreachable control flow nodes.
|
// unreachable control flow nodes.
|
||||||
if(p->link != nil && p->link->as == arch.ARET && p->link->mode == 1)
|
if(p->link != nil && p->link->as == ARET && p->link->mode == 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Collect basic blocks with selectgo calls.
|
// Collect basic blocks with selectgo calls.
|
||||||
@ -556,7 +556,7 @@ newcfg(Prog *firstp)
|
|||||||
if(bb->last->link != nil) {
|
if(bb->last->link != nil) {
|
||||||
// Add a fall-through when the instruction is
|
// Add a fall-through when the instruction is
|
||||||
// not an unconditional control transfer.
|
// not an unconditional control transfer.
|
||||||
if(bb->last->as != arch.AJMP && bb->last->as != arch.ARET && bb->last->as != arch.AUNDEF)
|
if(bb->last->as != AJMP && bb->last->as != ARET && bb->last->as != AUNDEF)
|
||||||
addedge(bb, bb->last->link->opt);
|
addedge(bb, bb->last->link->opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -678,7 +678,7 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
|
|||||||
bvresetall(avarinit);
|
bvresetall(avarinit);
|
||||||
|
|
||||||
arch.proginfo(&info, prog);
|
arch.proginfo(&info, prog);
|
||||||
if(prog->as == arch.ARET) {
|
if(prog->as == ARET) {
|
||||||
// Return instructions implicitly read all the arguments. For
|
// Return instructions implicitly read all the arguments. For
|
||||||
// the sake of correctness, out arguments must be read. For the
|
// the sake of correctness, out arguments must be read. For the
|
||||||
// sake of backtrace quality, we read in arguments as well.
|
// sake of backtrace quality, we read in arguments as well.
|
||||||
@ -711,7 +711,7 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(prog->as == arch.ATEXT) {
|
if(prog->as == ATEXT) {
|
||||||
// A text instruction marks the entry point to a function and
|
// A text instruction marks the entry point to a function and
|
||||||
// the definition point of all in arguments.
|
// the definition point of all in arguments.
|
||||||
for(i = 0; i < arraylength(vars); i++) {
|
for(i = 0; i < arraylength(vars); i++) {
|
||||||
@ -764,9 +764,9 @@ Next:
|
|||||||
if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != to->node)
|
if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != to->node)
|
||||||
fatal("bad bookkeeping in liveness %N %d", to->node, pos);
|
fatal("bad bookkeeping in liveness %N %d", to->node, pos);
|
||||||
if(((Node*)(to->node))->addrtaken) {
|
if(((Node*)(to->node))->addrtaken) {
|
||||||
if(prog->as != arch.AVARKILL)
|
if(prog->as != AVARKILL)
|
||||||
bvset(avarinit, pos);
|
bvset(avarinit, pos);
|
||||||
if(prog->as == arch.AVARDEF || prog->as == arch.AVARKILL)
|
if(prog->as == AVARDEF || prog->as == AVARKILL)
|
||||||
bvset(varkill, pos);
|
bvset(varkill, pos);
|
||||||
} else {
|
} else {
|
||||||
// RightRead is a read, obviously.
|
// RightRead is a read, obviously.
|
||||||
@ -780,7 +780,7 @@ Next:
|
|||||||
if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr)
|
if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr)
|
||||||
bvset(uevar, pos);
|
bvset(uevar, pos);
|
||||||
if(info.flags & RightWrite)
|
if(info.flags & RightWrite)
|
||||||
if(to->node != nil && (!arch.isfat(((Node*)(to->node))->type) || prog->as == arch.AVARDEF))
|
if(to->node != nil && (!arch.isfat(((Node*)(to->node))->type) || prog->as == AVARDEF))
|
||||||
bvset(varkill, pos);
|
bvset(varkill, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -952,7 +952,7 @@ livenessprintblock(Liveness *lv, BasicBlock *bb)
|
|||||||
print("\tprog:\n");
|
print("\tprog:\n");
|
||||||
for(prog = bb->first;; prog = prog->link) {
|
for(prog = bb->first;; prog = prog->link) {
|
||||||
print("\t\t%P", prog);
|
print("\t\t%P", prog);
|
||||||
if(prog->as == arch.APCDATA && prog->from.offset == PCDATA_StackMapIndex) {
|
if(prog->as == APCDATA && prog->from.offset == PCDATA_StackMapIndex) {
|
||||||
pos = prog->to.offset;
|
pos = prog->to.offset;
|
||||||
live = *(Bvec**)arrayget(lv->livepointers, pos);
|
live = *(Bvec**)arrayget(lv->livepointers, pos);
|
||||||
print(" ");
|
print(" ");
|
||||||
@ -1048,7 +1048,7 @@ checkptxt(Node *fn, Prog *firstp)
|
|||||||
for(p = firstp; p != P; p = p->link) {
|
for(p = firstp; p != P; p = p->link) {
|
||||||
if(0)
|
if(0)
|
||||||
print("analyzing '%P'\n", p);
|
print("analyzing '%P'\n", p);
|
||||||
if(p->as != arch.ADATA && p->as != arch.AGLOBL && p->as != arch.ANAME && p->as != arch.ASIGNAME && p->as != arch.ATYPE)
|
if(p->as != ADATA && p->as != AGLOBL && p->as != ATYPE)
|
||||||
checkprog(fn, p);
|
checkprog(fn, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1233,7 +1233,7 @@ newpcdataprog(Prog *prog, int32 index)
|
|||||||
|
|
||||||
nodconst(&from, types[TINT32], PCDATA_StackMapIndex);
|
nodconst(&from, types[TINT32], PCDATA_StackMapIndex);
|
||||||
nodconst(&to, types[TINT32], index);
|
nodconst(&to, types[TINT32], index);
|
||||||
pcdata = unlinkedprog(arch.APCDATA);
|
pcdata = unlinkedprog(APCDATA);
|
||||||
pcdata->lineno = prog->lineno;
|
pcdata->lineno = prog->lineno;
|
||||||
arch.naddr(&from, &pcdata->from, 0);
|
arch.naddr(&from, &pcdata->from, 0);
|
||||||
arch.naddr(&to, &pcdata->to, 0);
|
arch.naddr(&to, &pcdata->to, 0);
|
||||||
@ -1245,7 +1245,7 @@ newpcdataprog(Prog *prog, int32 index)
|
|||||||
static int
|
static int
|
||||||
issafepoint(Prog *prog)
|
issafepoint(Prog *prog)
|
||||||
{
|
{
|
||||||
return prog->as == arch.ATEXT || prog->as == arch.ACALL;
|
return prog->as == ATEXT || prog->as == ACALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes the sets for solving the live variables. Visits all the
|
// Initializes the sets for solving the live variables. Visits all the
|
||||||
@ -1542,7 +1542,7 @@ livenessepilogue(Liveness *lv)
|
|||||||
// walk backward, emit pcdata and populate the maps
|
// walk backward, emit pcdata and populate the maps
|
||||||
pos = bb->lastbitmapindex;
|
pos = bb->lastbitmapindex;
|
||||||
if(pos < 0) {
|
if(pos < 0) {
|
||||||
// the first block we encounter should have the arch.ATEXT so
|
// the first block we encounter should have the ATEXT so
|
||||||
// at no point should pos ever be less than zero.
|
// at no point should pos ever be less than zero.
|
||||||
fatal("livenessepilogue");
|
fatal("livenessepilogue");
|
||||||
}
|
}
|
||||||
@ -1569,7 +1569,7 @@ livenessepilogue(Liveness *lv)
|
|||||||
// Useful sanity check: on entry to the function,
|
// Useful sanity check: on entry to the function,
|
||||||
// the only things that can possibly be live are the
|
// the only things that can possibly be live are the
|
||||||
// input parameters.
|
// input parameters.
|
||||||
if(p->as == arch.ATEXT) {
|
if(p->as == ATEXT) {
|
||||||
for(j = 0; j < liveout->n; j++) {
|
for(j = 0; j < liveout->n; j++) {
|
||||||
if(!bvget(liveout, j))
|
if(!bvget(liveout, j))
|
||||||
continue;
|
continue;
|
||||||
@ -1587,7 +1587,7 @@ livenessepilogue(Liveness *lv)
|
|||||||
// Ambiguously live variables are zeroed immediately after
|
// Ambiguously live variables are zeroed immediately after
|
||||||
// function entry. Mark them live for all the non-entry bitmaps
|
// function entry. Mark them live for all the non-entry bitmaps
|
||||||
// so that GODEBUG=gcdead=1 mode does not poison them.
|
// so that GODEBUG=gcdead=1 mode does not poison them.
|
||||||
if(p->as == arch.ACALL)
|
if(p->as == ACALL)
|
||||||
bvor(locals, locals, ambig);
|
bvor(locals, locals, ambig);
|
||||||
|
|
||||||
// Show live pointer bitmaps.
|
// Show live pointer bitmaps.
|
||||||
@ -1597,9 +1597,9 @@ livenessepilogue(Liveness *lv)
|
|||||||
if(msg != nil) {
|
if(msg != nil) {
|
||||||
fmtstrinit(&fmt);
|
fmtstrinit(&fmt);
|
||||||
fmtprint(&fmt, "%L: live at ", p->lineno);
|
fmtprint(&fmt, "%L: live at ", p->lineno);
|
||||||
if(p->as == arch.ACALL && p->to.node)
|
if(p->as == ACALL && p->to.node)
|
||||||
fmtprint(&fmt, "call to %s:", ((Node*)(p->to.node))->sym->name);
|
fmtprint(&fmt, "call to %s:", ((Node*)(p->to.node))->sym->name);
|
||||||
else if(p->as == arch.ACALL)
|
else if(p->as == ACALL)
|
||||||
fmtprint(&fmt, "indirect call:");
|
fmtprint(&fmt, "indirect call:");
|
||||||
else
|
else
|
||||||
fmtprint(&fmt, "entry to %s:", ((Node*)(p->from.node))->sym->name);
|
fmtprint(&fmt, "entry to %s:", ((Node*)(p->from.node))->sym->name);
|
||||||
@ -1620,7 +1620,7 @@ livenessepilogue(Liveness *lv)
|
|||||||
|
|
||||||
// Only CALL instructions need a PCDATA annotation.
|
// Only CALL instructions need a PCDATA annotation.
|
||||||
// The TEXT instruction annotation is implicit.
|
// The TEXT instruction annotation is implicit.
|
||||||
if(p->as == arch.ACALL) {
|
if(p->as == ACALL) {
|
||||||
if(isdeferreturn(p)) {
|
if(isdeferreturn(p)) {
|
||||||
// runtime.deferreturn modifies its return address to return
|
// runtime.deferreturn modifies its return address to return
|
||||||
// back to the CALL, not to the subsequent instruction.
|
// back to the CALL, not to the subsequent instruction.
|
||||||
@ -1768,7 +1768,7 @@ livenesscompact(Liveness *lv)
|
|||||||
|
|
||||||
// Rewrite PCDATA instructions to use new numbering.
|
// Rewrite PCDATA instructions to use new numbering.
|
||||||
for(p=lv->ptxt; p != P; p=p->link) {
|
for(p=lv->ptxt; p != P; p=p->link) {
|
||||||
if(p->as == arch.APCDATA && p->from.offset == PCDATA_StackMapIndex) {
|
if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex) {
|
||||||
i = p->to.offset;
|
i = p->to.offset;
|
||||||
if(i >= 0)
|
if(i >= 0)
|
||||||
p->to.offset = remap[i];
|
p->to.offset = remap[i];
|
||||||
@ -1855,7 +1855,7 @@ livenessprintdebug(Liveness *lv)
|
|||||||
// program listing, with individual effects listed
|
// program listing, with individual effects listed
|
||||||
for(p = bb->first;; p = p->link) {
|
for(p = bb->first;; p = p->link) {
|
||||||
print("%P\n", p);
|
print("%P\n", p);
|
||||||
if(p->as == arch.APCDATA && p->from.offset == PCDATA_StackMapIndex)
|
if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex)
|
||||||
pcdata = p->to.offset;
|
pcdata = p->to.offset;
|
||||||
progeffects(p, lv->vars, uevar, varkill, avarinit);
|
progeffects(p, lv->vars, uevar, varkill, avarinit);
|
||||||
printed = 0;
|
printed = 0;
|
||||||
|
@ -81,7 +81,7 @@ chasejmp(Prog *p, int *jmploop)
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
while(p != P && p->as == arch.AJMP && p->to.type == TYPE_BRANCH) {
|
while(p != P && p->as == AJMP && p->to.type == TYPE_BRANCH) {
|
||||||
if(++n > 10) {
|
if(++n > 10) {
|
||||||
*jmploop = 1;
|
*jmploop = 1;
|
||||||
break;
|
break;
|
||||||
@ -112,9 +112,9 @@ mark(Prog *firstp)
|
|||||||
if(p->opt != dead)
|
if(p->opt != dead)
|
||||||
break;
|
break;
|
||||||
p->opt = alive;
|
p->opt = alive;
|
||||||
if(p->as != arch.ACALL && p->to.type == TYPE_BRANCH && p->to.u.branch)
|
if(p->as != ACALL && p->to.type == TYPE_BRANCH && p->to.u.branch)
|
||||||
mark(p->to.u.branch);
|
mark(p->to.u.branch);
|
||||||
if(p->as == arch.AJMP || p->as == arch.ARET || p->as == arch.AUNDEF)
|
if(p->as == AJMP || p->as == ARET || p->as == AUNDEF)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ fixjmp(Prog *firstp)
|
|||||||
for(p=firstp; p; p=p->link) {
|
for(p=firstp; p; p=p->link) {
|
||||||
if(debug['R'] && debug['v'])
|
if(debug['R'] && debug['v'])
|
||||||
print("%P\n", p);
|
print("%P\n", p);
|
||||||
if(p->as != arch.ACALL && p->to.type == TYPE_BRANCH && p->to.u.branch && p->to.u.branch->as == arch.AJMP) {
|
if(p->as != ACALL && p->to.type == TYPE_BRANCH && p->to.u.branch && p->to.u.branch->as == AJMP) {
|
||||||
p->to.u.branch = chasejmp(p->to.u.branch, &jmploop);
|
p->to.u.branch = chasejmp(p->to.u.branch, &jmploop);
|
||||||
if(debug['R'] && debug['v'])
|
if(debug['R'] && debug['v'])
|
||||||
print("->%P\n", p);
|
print("->%P\n", p);
|
||||||
@ -150,8 +150,8 @@ fixjmp(Prog *firstp)
|
|||||||
last = nil;
|
last = nil;
|
||||||
for(p=firstp; p; p=p->link) {
|
for(p=firstp; p; p=p->link) {
|
||||||
if(p->opt == dead) {
|
if(p->opt == dead) {
|
||||||
if(p->link == P && p->as == arch.ARET && last && last->as != arch.ARET) {
|
if(p->link == P && p->as == ARET && last && last->as != ARET) {
|
||||||
// This is the final arch.ARET, and the code so far doesn't have one.
|
// This is the final ARET, and the code so far doesn't have one.
|
||||||
// Let it stay. The register allocator assumes that all live code in
|
// Let it stay. The register allocator assumes that all live code in
|
||||||
// the function can be traversed by starting at all the RET instructions
|
// the function can be traversed by starting at all the RET instructions
|
||||||
// and following predecessor links. If we remove the final RET,
|
// and following predecessor links. If we remove the final RET,
|
||||||
@ -176,7 +176,7 @@ fixjmp(Prog *firstp)
|
|||||||
if(!jmploop) {
|
if(!jmploop) {
|
||||||
last = nil;
|
last = nil;
|
||||||
for(p=firstp; p; p=p->link) {
|
for(p=firstp; p; p=p->link) {
|
||||||
if(p->as == arch.AJMP && p->to.type == TYPE_BRANCH && p->to.u.branch == p->link) {
|
if(p->as == AJMP && p->to.type == TYPE_BRANCH && p->to.u.branch == p->link) {
|
||||||
if(debug['R'] && debug['v'])
|
if(debug['R'] && debug['v'])
|
||||||
print("del %P\n", p);
|
print("del %P\n", p);
|
||||||
continue;
|
continue;
|
||||||
@ -620,7 +620,7 @@ mergetemp(Prog *firstp)
|
|||||||
p = r->f.prog;
|
p = r->f.prog;
|
||||||
arch.proginfo(&info, p);
|
arch.proginfo(&info, p);
|
||||||
if(p->to.node == v->node && (info.flags & RightWrite) && !(info.flags & RightRead)) {
|
if(p->to.node == v->node && (info.flags & RightWrite) && !(info.flags & RightRead)) {
|
||||||
p->as = arch.ANOP;
|
p->as = ANOP;
|
||||||
p->to = zprog.to;
|
p->to = zprog.to;
|
||||||
v->removed = 1;
|
v->removed = 1;
|
||||||
if(Debug)
|
if(Debug)
|
||||||
@ -813,7 +813,7 @@ varkillwalk(TempVar *v, TempFlow *r0, uint32 gen)
|
|||||||
v->end = p->pc;
|
v->end = p->pc;
|
||||||
if(v->start > p->pc)
|
if(v->start > p->pc)
|
||||||
v->start = p->pc;
|
v->start = p->pc;
|
||||||
if(p->as == arch.ARET || (p->as == arch.AVARKILL && p->to.node == v->node))
|
if(p->as == ARET || (p->as == AVARKILL && p->to.node == v->node))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,7 +865,7 @@ nilopt(Prog *firstp)
|
|||||||
nkill = 0;
|
nkill = 0;
|
||||||
for(r = (NilFlow*)g->start; r != nil; r = (NilFlow*)r->f.link) {
|
for(r = (NilFlow*)g->start; r != nil; r = (NilFlow*)r->f.link) {
|
||||||
p = r->f.prog;
|
p = r->f.prog;
|
||||||
if(p->as != arch.ACHECKNIL || !arch.regtyp(&p->from))
|
if(p->as != ACHECKNIL || !arch.regtyp(&p->from))
|
||||||
continue;
|
continue;
|
||||||
ncheck++;
|
ncheck++;
|
||||||
if(arch.stackaddr(&p->from)) {
|
if(arch.stackaddr(&p->from)) {
|
||||||
@ -916,7 +916,7 @@ nilwalkback(NilFlow *rcheck)
|
|||||||
// without first finding the check, so this one is unchecked.
|
// without first finding the check, so this one is unchecked.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(r != rcheck && p->as == arch.ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from)) {
|
if(r != rcheck && p->as == ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from)) {
|
||||||
rcheck->kill = 1;
|
rcheck->kill = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -937,7 +937,7 @@ nilwalkback(NilFlow *rcheck)
|
|||||||
|
|
||||||
// If same check, stop this loop but still check
|
// If same check, stop this loop but still check
|
||||||
// alternate predecessors up to this point.
|
// alternate predecessors up to this point.
|
||||||
if(r1 != rcheck && p->as == arch.ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from))
|
if(r1 != rcheck && p->as == ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
arch.proginfo(&info, p);
|
arch.proginfo(&info, p);
|
||||||
@ -993,7 +993,7 @@ nilwalkfwd(NilFlow *rcheck)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop if another nil check happens.
|
// Stop if another nil check happens.
|
||||||
if(p->as == arch.ACHECKNIL)
|
if(p->as == ACHECKNIL)
|
||||||
return;
|
return;
|
||||||
// Stop if value is lost.
|
// Stop if value is lost.
|
||||||
if((info.flags & RightWrite) && arch.sameaddr(&p->to, &rcheck->f.prog->from))
|
if((info.flags & RightWrite) && arch.sameaddr(&p->to, &rcheck->f.prog->from))
|
||||||
|
@ -2187,13 +2187,13 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
|
|||||||
o1 = oprrr(ctxt, p->as, p->scond);
|
o1 = oprrr(ctxt, p->as, p->scond);
|
||||||
o1 |= ((p->from.reg&15)<<0);
|
o1 |= ((p->from.reg&15)<<0);
|
||||||
o1 |= ((FREGTMP&15)<<12);
|
o1 |= ((FREGTMP&15)<<12);
|
||||||
o2 = oprrr(ctxt, AMOVFW+AEND, p->scond);
|
o2 = oprrr(ctxt, AMOVFW+ALAST, p->scond);
|
||||||
o2 |= ((FREGTMP&15)<<16);
|
o2 |= ((FREGTMP&15)<<16);
|
||||||
o2 |= ((p->to.reg&15)<<12);
|
o2 |= ((p->to.reg&15)<<12);
|
||||||
break;
|
break;
|
||||||
case 87: /* movwf reg,freg - fix-to-float */
|
case 87: /* movwf reg,freg - fix-to-float */
|
||||||
// macro for movw reg,FTMP; movwf FTMP,freg
|
// macro for movw reg,FTMP; movwf FTMP,freg
|
||||||
o1 = oprrr(ctxt, AMOVWF+AEND, p->scond);
|
o1 = oprrr(ctxt, AMOVWF+ALAST, p->scond);
|
||||||
o1 |= ((p->from.reg&15)<<12);
|
o1 |= ((p->from.reg&15)<<12);
|
||||||
o1 |= ((FREGTMP&15)<<16);
|
o1 |= ((FREGTMP&15)<<16);
|
||||||
o2 = oprrr(ctxt, p->as, p->scond);
|
o2 = oprrr(ctxt, p->as, p->scond);
|
||||||
@ -2201,17 +2201,17 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
|
|||||||
o2 |= ((p->to.reg&15)<<12);
|
o2 |= ((p->to.reg&15)<<12);
|
||||||
break;
|
break;
|
||||||
case 88: /* movw reg,freg */
|
case 88: /* movw reg,freg */
|
||||||
o1 = oprrr(ctxt, AMOVWF+AEND, p->scond);
|
o1 = oprrr(ctxt, AMOVWF+ALAST, p->scond);
|
||||||
o1 |= ((p->from.reg&15)<<12);
|
o1 |= ((p->from.reg&15)<<12);
|
||||||
o1 |= ((p->to.reg&15)<<16);
|
o1 |= ((p->to.reg&15)<<16);
|
||||||
break;
|
break;
|
||||||
case 89: /* movw freg,reg */
|
case 89: /* movw freg,reg */
|
||||||
o1 = oprrr(ctxt, AMOVFW+AEND, p->scond);
|
o1 = oprrr(ctxt, AMOVFW+ALAST, p->scond);
|
||||||
o1 |= ((p->from.reg&15)<<16);
|
o1 |= ((p->from.reg&15)<<16);
|
||||||
o1 |= ((p->to.reg&15)<<12);
|
o1 |= ((p->to.reg&15)<<12);
|
||||||
break;
|
break;
|
||||||
case 90: /* tst reg */
|
case 90: /* tst reg */
|
||||||
o1 = oprrr(ctxt, ACMP+AEND, p->scond);
|
o1 = oprrr(ctxt, ACMP+ALAST, p->scond);
|
||||||
o1 |= (p->from.reg&15)<<16;
|
o1 |= (p->from.reg&15)<<16;
|
||||||
break;
|
break;
|
||||||
case 91: /* ldrexd oreg,reg */
|
case 91: /* ldrexd oreg,reg */
|
||||||
@ -2416,11 +2416,11 @@ oprrr(Link *ctxt, int a, int sc)
|
|||||||
return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
|
return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
|
||||||
(1<<18) | (1<<8) | (1<<7); // toint, double, trunc
|
(1<<18) | (1<<8) | (1<<7); // toint, double, trunc
|
||||||
|
|
||||||
case AMOVWF+AEND: // copy WtoF
|
case AMOVWF+ALAST: // copy WtoF
|
||||||
return o | (0xe<<24) | (0x0<<20) | (0xb<<8) | (1<<4);
|
return o | (0xe<<24) | (0x0<<20) | (0xb<<8) | (1<<4);
|
||||||
case AMOVFW+AEND: // copy FtoW
|
case AMOVFW+ALAST: // copy FtoW
|
||||||
return o | (0xe<<24) | (0x1<<20) | (0xb<<8) | (1<<4);
|
return o | (0xe<<24) | (0x1<<20) | (0xb<<8) | (1<<4);
|
||||||
case ACMP+AEND: // cmp imm
|
case ACMP+ALAST: // cmp imm
|
||||||
return o | (0x3<<24) | (0x5<<20);
|
return o | (0x3<<24) | (0x5<<20);
|
||||||
|
|
||||||
case ACLZ:
|
case ACLZ:
|
||||||
|
@ -990,7 +990,6 @@ static Optab optab[] =
|
|||||||
{ AFXRSTOR64, ysvrs, Pw, {0x0f,0xae,(01),0x0f,0xae,(01)} },
|
{ AFXRSTOR64, ysvrs, Pw, {0x0f,0xae,(01),0x0f,0xae,(01)} },
|
||||||
{ AFXSAVE64, ysvrs, Pw, {0x0f,0xae,(00),0x0f,0xae,(00)} },
|
{ AFXSAVE64, ysvrs, Pw, {0x0f,0xae,(00),0x0f,0xae,(00)} },
|
||||||
{ AGLOBL },
|
{ AGLOBL },
|
||||||
{ AHISTORY },
|
|
||||||
{ AHLT, ynone, Px, {0xf4} },
|
{ AHLT, ynone, Px, {0xf4} },
|
||||||
{ AIDIVB, ydivb, Pb, {0xf6,(07)} },
|
{ AIDIVB, ydivb, Pb, {0xf6,(07)} },
|
||||||
{ AIDIVL, ydivl, Px, {0xf7,(07)} },
|
{ AIDIVL, ydivl, Px, {0xf7,(07)} },
|
||||||
@ -1115,7 +1114,6 @@ static Optab optab[] =
|
|||||||
{ AMULSD, yxm, Pf2, {0x59} },
|
{ AMULSD, yxm, Pf2, {0x59} },
|
||||||
{ AMULSS, yxm, Pf3, {0x59} },
|
{ AMULSS, yxm, Pf3, {0x59} },
|
||||||
{ AMULW, ydivl, Pe, {0xf7,(04)} },
|
{ AMULW, ydivl, Pe, {0xf7,(04)} },
|
||||||
{ ANAME },
|
|
||||||
{ ANEGB, yscond, Pb, {0xf6,(03)} },
|
{ ANEGB, yscond, Pb, {0xf6,(03)} },
|
||||||
{ ANEGL, yscond, Px, {0xf7,(03)} },
|
{ ANEGL, yscond, Px, {0xf7,(03)} },
|
||||||
{ ANEGQ, yscond, Pw, {0xf7,(03)} },
|
{ ANEGQ, yscond, Pw, {0xf7,(03)} },
|
||||||
|
@ -53,6 +53,8 @@ struct Optab
|
|||||||
uchar op[13];
|
uchar op[13];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Optab* opindex[ALAST+1];
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
Yxxx = 0,
|
Yxxx = 0,
|
||||||
@ -675,7 +677,6 @@ static Optab optab[] =
|
|||||||
{ ADIVW, ydivl, Pe, {0xf7,(06)} },
|
{ ADIVW, ydivl, Pe, {0xf7,(06)} },
|
||||||
{ AENTER }, /* botch */
|
{ AENTER }, /* botch */
|
||||||
{ AGLOBL },
|
{ AGLOBL },
|
||||||
{ AHISTORY },
|
|
||||||
{ AHLT, ynone, Px, {0xf4} },
|
{ AHLT, ynone, Px, {0xf4} },
|
||||||
{ AIDIVB, ydivb, Pb, {0xf6,(07)} },
|
{ AIDIVB, ydivb, Pb, {0xf6,(07)} },
|
||||||
{ AIDIVL, ydivl, Px, {0xf7,(07)} },
|
{ AIDIVL, ydivl, Px, {0xf7,(07)} },
|
||||||
@ -748,7 +749,6 @@ static Optab optab[] =
|
|||||||
{ AMULB, ydivb, Pb, {0xf6,(04)} },
|
{ AMULB, ydivb, Pb, {0xf6,(04)} },
|
||||||
{ AMULL, ydivl, Px, {0xf7,(04)} },
|
{ AMULL, ydivl, Px, {0xf7,(04)} },
|
||||||
{ AMULW, ydivl, Pe, {0xf7,(04)} },
|
{ AMULW, ydivl, Pe, {0xf7,(04)} },
|
||||||
{ ANAME },
|
|
||||||
{ ANEGB, yscond, Px, {0xf6,(03)} },
|
{ ANEGB, yscond, Px, {0xf6,(03)} },
|
||||||
{ ANEGL, yscond, Px, {0xf7,(03)} }, // TODO(rsc): yscond is wrong here.
|
{ ANEGL, yscond, Px, {0xf7,(03)} }, // TODO(rsc): yscond is wrong here.
|
||||||
{ ANEGW, yscond, Pe, {0xf7,(03)} }, // TODO(rsc): yscond is wrong here.
|
{ ANEGW, yscond, Pe, {0xf7,(03)} }, // TODO(rsc): yscond is wrong here.
|
||||||
@ -967,9 +967,6 @@ static Optab optab[] =
|
|||||||
{ AFYL2X, ynone, Px, {0xd9, 0xf1} },
|
{ AFYL2X, ynone, Px, {0xd9, 0xf1} },
|
||||||
{ AFYL2XP1, ynone, Px, {0xd9, 0xf9} },
|
{ AFYL2XP1, ynone, Px, {0xd9, 0xf9} },
|
||||||
{ AEND },
|
{ AEND },
|
||||||
{ ADYNT_ },
|
|
||||||
{ AINIT_ },
|
|
||||||
{ ASIGNAME },
|
|
||||||
{ ACMPXCHGB, yrb_mb, Pm, {0xb0} },
|
{ ACMPXCHGB, yrb_mb, Pm, {0xb0} },
|
||||||
{ ACMPXCHGL, yrl_ml, Pm, {0xb1} },
|
{ ACMPXCHGL, yrl_ml, Pm, {0xb1} },
|
||||||
{ ACMPXCHGW, yrl_ml, Pm, {0xb1} },
|
{ ACMPXCHGW, yrl_ml, Pm, {0xb1} },
|
||||||
@ -1379,11 +1376,14 @@ span8(Link *ctxt, LSym *s)
|
|||||||
static void
|
static void
|
||||||
instinit(void)
|
instinit(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i, c;
|
||||||
|
|
||||||
for(i=1; optab[i].as; i++)
|
for(i=1; optab[i].as; i++) {
|
||||||
if(i != optab[i].as)
|
c = optab[i].as;
|
||||||
sysfatal("phase error in optab: at %A found %A", i, optab[i].as);
|
if(opindex[c] != nil)
|
||||||
|
sysfatal("phase error in optab: %d (%A)", i, c);
|
||||||
|
opindex[c] = &optab[i];
|
||||||
|
}
|
||||||
|
|
||||||
for(i=0; i<Ymax; i++)
|
for(i=0; i<Ymax; i++)
|
||||||
ycover[i*Ymax + i] = 1;
|
ycover[i*Ymax + i] = 1;
|
||||||
@ -2198,7 +2198,7 @@ doasm(Link *ctxt, Prog *p)
|
|||||||
|
|
||||||
ft = p->ft * Ymax;
|
ft = p->ft * Ymax;
|
||||||
tt = p->tt * Ymax;
|
tt = p->tt * Ymax;
|
||||||
o = &optab[p->as];
|
o = opindex[p->as];
|
||||||
t = o->ytab;
|
t = o->ytab;
|
||||||
if(t == 0) {
|
if(t == 0) {
|
||||||
ctxt->diag("asmins: noproto %P", p);
|
ctxt->diag("asmins: noproto %P", p);
|
||||||
|
@ -1788,7 +1788,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
|
|||||||
r = p->to.reg;
|
r = p->to.reg;
|
||||||
if(p->as == AADD && (!r0iszero && p->reg == 0 || r0iszero && p->to.reg == 0))
|
if(p->as == AADD && (!r0iszero && p->reg == 0 || r0iszero && p->to.reg == 0))
|
||||||
ctxt->diag("literal operation on R0\n%P", p);
|
ctxt->diag("literal operation on R0\n%P", p);
|
||||||
o1 = AOP_IRR(opirr(ctxt, p->as+AEND), p->to.reg, r, v>>16);
|
o1 = AOP_IRR(opirr(ctxt, p->as+ALAST), p->to.reg, r, v>>16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
|
case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
|
||||||
@ -2157,7 +2157,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
|
|||||||
r = p->reg;
|
r = p->reg;
|
||||||
if(r == 0)
|
if(r == 0)
|
||||||
r = p->to.reg;
|
r = p->to.reg;
|
||||||
o1 = LOP_IRR(opirr(ctxt, p->as+AEND), p->to.reg, r, v>>16); /* oris, xoris, andis */
|
o1 = LOP_IRR(opirr(ctxt, p->as+ALAST), p->to.reg, r, v>>16); /* oris, xoris, andis */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 60: /* tw to,a,b */
|
case 60: /* tw to,a,b */
|
||||||
@ -2632,10 +2632,10 @@ opirr(Link *ctxt, int a)
|
|||||||
case AADD: return OPVCC(14,0,0,0);
|
case AADD: return OPVCC(14,0,0,0);
|
||||||
case AADDC: return OPVCC(12,0,0,0);
|
case AADDC: return OPVCC(12,0,0,0);
|
||||||
case AADDCCC: return OPVCC(13,0,0,0);
|
case AADDCCC: return OPVCC(13,0,0,0);
|
||||||
case AADD+AEND: return OPVCC(15,0,0,0); /* ADDIS/CAU */
|
case AADD+ALAST: return OPVCC(15,0,0,0); /* ADDIS/CAU */
|
||||||
|
|
||||||
case AANDCC: return OPVCC(28,0,0,0);
|
case AANDCC: return OPVCC(28,0,0,0);
|
||||||
case AANDCC+AEND: return OPVCC(29,0,0,0); /* ANDIS./ANDIU. */
|
case AANDCC+ALAST: return OPVCC(29,0,0,0); /* ANDIS./ANDIU. */
|
||||||
|
|
||||||
case ABR: return OPVCC(18,0,0,0);
|
case ABR: return OPVCC(18,0,0,0);
|
||||||
case ABL: return OPVCC(18,0,0,0) | 1;
|
case ABL: return OPVCC(18,0,0,0) | 1;
|
||||||
@ -2662,7 +2662,7 @@ opirr(Link *ctxt, int a)
|
|||||||
case AMULLW: return OPVCC(7,0,0,0);
|
case AMULLW: return OPVCC(7,0,0,0);
|
||||||
|
|
||||||
case AOR: return OPVCC(24,0,0,0);
|
case AOR: return OPVCC(24,0,0,0);
|
||||||
case AOR+AEND: return OPVCC(25,0,0,0); /* ORIS/ORIU */
|
case AOR+ALAST: return OPVCC(25,0,0,0); /* ORIS/ORIU */
|
||||||
|
|
||||||
case ARLWMI: return OPVCC(20,0,0,0); /* rlwimi */
|
case ARLWMI: return OPVCC(20,0,0,0); /* rlwimi */
|
||||||
case ARLWMICC: return OPVCC(20,0,0,1);
|
case ARLWMICC: return OPVCC(20,0,0,1);
|
||||||
@ -2692,7 +2692,7 @@ opirr(Link *ctxt, int a)
|
|||||||
case ATD: return OPVCC(2,0,0,0);
|
case ATD: return OPVCC(2,0,0,0);
|
||||||
|
|
||||||
case AXOR: return OPVCC(26,0,0,0); /* XORIL */
|
case AXOR: return OPVCC(26,0,0,0); /* XORIL */
|
||||||
case AXOR+AEND: return OPVCC(27,0,0,0); /* XORIU */
|
case AXOR+ALAST: return OPVCC(27,0,0,0); /* XORIU */
|
||||||
}
|
}
|
||||||
ctxt->diag("bad opcode i/r %A", a);
|
ctxt->diag("bad opcode i/r %A", a);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -93,7 +93,7 @@ Pconv(Fmt *fp)
|
|||||||
a = p->as;
|
a = p->as;
|
||||||
|
|
||||||
str[0] = 0;
|
str[0] = 0;
|
||||||
if(a == ADATA || a == AINIT || a == ADYNT)
|
if(a == ADATA)
|
||||||
sprint(str, "%.5lld (%L) %A %D/%lld,%D", p->pc, p->lineno, a, &p->from, p->from3.offset, &p->to);
|
sprint(str, "%.5lld (%L) %A %D/%lld,%D", p->pc, p->lineno, a, &p->from, p->from3.offset, &p->to);
|
||||||
else if(a == ATEXT || a == AGLOBL) {
|
else if(a == ATEXT || a == AGLOBL) {
|
||||||
if(p->from3.offset != 0)
|
if(p->from3.offset != 0)
|
||||||
|
@ -35,18 +35,6 @@
|
|||||||
#include "../cmd/5l/5.out.h"
|
#include "../cmd/5l/5.out.h"
|
||||||
#include "../runtime/stack.h"
|
#include "../runtime/stack.h"
|
||||||
|
|
||||||
static int
|
|
||||||
isdata(Prog *p)
|
|
||||||
{
|
|
||||||
return p->as == ADATA || p->as == AGLOBL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
iscall(Prog *p)
|
|
||||||
{
|
|
||||||
return p->as == ABL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
progedit(Link *ctxt, Prog *p)
|
progedit(Link *ctxt, Prog *p)
|
||||||
{
|
{
|
||||||
@ -1010,24 +998,9 @@ LinkArch linkarm = {
|
|||||||
.preprocess = preprocess,
|
.preprocess = preprocess,
|
||||||
.assemble = span5,
|
.assemble = span5,
|
||||||
.follow = follow,
|
.follow = follow,
|
||||||
.iscall = iscall,
|
|
||||||
.isdata = isdata,
|
|
||||||
.progedit = progedit,
|
.progedit = progedit,
|
||||||
|
|
||||||
.minlc = 4,
|
.minlc = 4,
|
||||||
.ptrsize = 4,
|
.ptrsize = 4,
|
||||||
.regsize = 4,
|
.regsize = 4,
|
||||||
|
|
||||||
.ACALL = ABL,
|
|
||||||
.ADATA = ADATA,
|
|
||||||
.AEND = AEND,
|
|
||||||
.AFUNCDATA = AFUNCDATA,
|
|
||||||
.AGLOBL = AGLOBL,
|
|
||||||
.AJMP = AB,
|
|
||||||
.ANOP = ANOP,
|
|
||||||
.APCDATA = APCDATA,
|
|
||||||
.ARET = ARET,
|
|
||||||
.ATEXT = ATEXT,
|
|
||||||
.ATYPE = ATYPE,
|
|
||||||
.AUSEFIELD = AUSEFIELD,
|
|
||||||
};
|
};
|
||||||
|
@ -47,18 +47,6 @@ nopout(Prog *p)
|
|||||||
p->to.name = 0;
|
p->to.name = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
isdata(Prog *p)
|
|
||||||
{
|
|
||||||
return p->as == ADATA || p->as == AGLOBL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
iscall(Prog *p)
|
|
||||||
{
|
|
||||||
return p->as == ACALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nacladdr(Link*, Prog*, Addr*);
|
static void nacladdr(Link*, Prog*, Addr*);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1047,26 +1035,11 @@ LinkArch linkamd64 = {
|
|||||||
.preprocess = preprocess,
|
.preprocess = preprocess,
|
||||||
.assemble = span6,
|
.assemble = span6,
|
||||||
.follow = follow,
|
.follow = follow,
|
||||||
.iscall = iscall,
|
|
||||||
.isdata = isdata,
|
|
||||||
.progedit = progedit,
|
.progedit = progedit,
|
||||||
|
|
||||||
.minlc = 1,
|
.minlc = 1,
|
||||||
.ptrsize = 8,
|
.ptrsize = 8,
|
||||||
.regsize = 8,
|
.regsize = 8,
|
||||||
|
|
||||||
.ACALL = ACALL,
|
|
||||||
.ADATA = ADATA,
|
|
||||||
.AEND = AEND,
|
|
||||||
.AFUNCDATA = AFUNCDATA,
|
|
||||||
.AGLOBL = AGLOBL,
|
|
||||||
.AJMP = AJMP,
|
|
||||||
.ANOP = ANOP,
|
|
||||||
.APCDATA = APCDATA,
|
|
||||||
.ARET = ARET,
|
|
||||||
.ATEXT = ATEXT,
|
|
||||||
.ATYPE = ATYPE,
|
|
||||||
.AUSEFIELD = AUSEFIELD,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
LinkArch linkamd64p32 = {
|
LinkArch linkamd64p32 = {
|
||||||
@ -1077,24 +1050,9 @@ LinkArch linkamd64p32 = {
|
|||||||
.preprocess = preprocess,
|
.preprocess = preprocess,
|
||||||
.assemble = span6,
|
.assemble = span6,
|
||||||
.follow = follow,
|
.follow = follow,
|
||||||
.iscall = iscall,
|
|
||||||
.isdata = isdata,
|
|
||||||
.progedit = progedit,
|
.progedit = progedit,
|
||||||
|
|
||||||
.minlc = 1,
|
.minlc = 1,
|
||||||
.ptrsize = 4,
|
.ptrsize = 4,
|
||||||
.regsize = 8,
|
.regsize = 8,
|
||||||
|
|
||||||
.ACALL = ACALL,
|
|
||||||
.ADATA = ADATA,
|
|
||||||
.AEND = AEND,
|
|
||||||
.AFUNCDATA = AFUNCDATA,
|
|
||||||
.AGLOBL = AGLOBL,
|
|
||||||
.AJMP = AJMP,
|
|
||||||
.ANOP = ANOP,
|
|
||||||
.APCDATA = APCDATA,
|
|
||||||
.ARET = ARET,
|
|
||||||
.ATEXT = ATEXT,
|
|
||||||
.ATYPE = ATYPE,
|
|
||||||
.AUSEFIELD = AUSEFIELD,
|
|
||||||
};
|
};
|
||||||
|
@ -35,18 +35,6 @@
|
|||||||
#include "../cmd/8l/8.out.h"
|
#include "../cmd/8l/8.out.h"
|
||||||
#include "../runtime/stack.h"
|
#include "../runtime/stack.h"
|
||||||
|
|
||||||
static int
|
|
||||||
isdata(Prog *p)
|
|
||||||
{
|
|
||||||
return p->as == ADATA || p->as == AGLOBL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
iscall(Prog *p)
|
|
||||||
{
|
|
||||||
return p->as == ACALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
canuselocaltls(Link *ctxt)
|
canuselocaltls(Link *ctxt)
|
||||||
{
|
{
|
||||||
@ -846,24 +834,9 @@ LinkArch link386 = {
|
|||||||
.preprocess = preprocess,
|
.preprocess = preprocess,
|
||||||
.assemble = span8,
|
.assemble = span8,
|
||||||
.follow = follow,
|
.follow = follow,
|
||||||
.iscall = iscall,
|
|
||||||
.isdata = isdata,
|
|
||||||
.progedit = progedit,
|
.progedit = progedit,
|
||||||
|
|
||||||
.minlc = 1,
|
.minlc = 1,
|
||||||
.ptrsize = 4,
|
.ptrsize = 4,
|
||||||
.regsize = 4,
|
.regsize = 4,
|
||||||
|
|
||||||
.ACALL = ACALL,
|
|
||||||
.ADATA = ADATA,
|
|
||||||
.AEND = AEND,
|
|
||||||
.AFUNCDATA = AFUNCDATA,
|
|
||||||
.AGLOBL = AGLOBL,
|
|
||||||
.AJMP = AJMP,
|
|
||||||
.ANOP = ANOP,
|
|
||||||
.APCDATA = APCDATA,
|
|
||||||
.ARET = ARET,
|
|
||||||
.ATEXT = ATEXT,
|
|
||||||
.ATYPE = ATYPE,
|
|
||||||
.AUSEFIELD = AUSEFIELD,
|
|
||||||
};
|
};
|
||||||
|
@ -35,18 +35,6 @@
|
|||||||
#include "../runtime/stack.h"
|
#include "../runtime/stack.h"
|
||||||
#include "../runtime/funcdata.h"
|
#include "../runtime/funcdata.h"
|
||||||
|
|
||||||
static int
|
|
||||||
isdata(Prog *p)
|
|
||||||
{
|
|
||||||
return p->as == ADATA || p->as == AGLOBL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
iscall(Prog *p)
|
|
||||||
{
|
|
||||||
return p->as == ABL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
progedit(Link *ctxt, Prog *p)
|
progedit(Link *ctxt, Prog *p)
|
||||||
{
|
{
|
||||||
@ -933,26 +921,11 @@ LinkArch linkppc64 = {
|
|||||||
.preprocess = preprocess,
|
.preprocess = preprocess,
|
||||||
.assemble = span9,
|
.assemble = span9,
|
||||||
.follow = follow,
|
.follow = follow,
|
||||||
.iscall = iscall,
|
|
||||||
.isdata = isdata,
|
|
||||||
.progedit = progedit,
|
.progedit = progedit,
|
||||||
|
|
||||||
.minlc = 4,
|
.minlc = 4,
|
||||||
.ptrsize = 8,
|
.ptrsize = 8,
|
||||||
.regsize = 8,
|
.regsize = 8,
|
||||||
|
|
||||||
.ACALL = ABL,
|
|
||||||
.ADATA = ADATA,
|
|
||||||
.AEND = AEND,
|
|
||||||
.AFUNCDATA = AFUNCDATA,
|
|
||||||
.AGLOBL = AGLOBL,
|
|
||||||
.AJMP = ABR,
|
|
||||||
.ANOP = ANOP,
|
|
||||||
.APCDATA = APCDATA,
|
|
||||||
.ARET = ARETURN,
|
|
||||||
.ATEXT = ATEXT,
|
|
||||||
.ATYPE = ATYPE,
|
|
||||||
.AUSEFIELD = AUSEFIELD,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
LinkArch linkppc64le = {
|
LinkArch linkppc64le = {
|
||||||
@ -963,24 +936,9 @@ LinkArch linkppc64le = {
|
|||||||
.preprocess = preprocess,
|
.preprocess = preprocess,
|
||||||
.assemble = span9,
|
.assemble = span9,
|
||||||
.follow = follow,
|
.follow = follow,
|
||||||
.iscall = iscall,
|
|
||||||
.isdata = isdata,
|
|
||||||
.progedit = progedit,
|
.progedit = progedit,
|
||||||
|
|
||||||
.minlc = 4,
|
.minlc = 4,
|
||||||
.ptrsize = 8,
|
.ptrsize = 8,
|
||||||
.regsize = 8,
|
.regsize = 8,
|
||||||
|
|
||||||
.ACALL = ABL,
|
|
||||||
.ADATA = ADATA,
|
|
||||||
.AEND = AEND,
|
|
||||||
.AFUNCDATA = AFUNCDATA,
|
|
||||||
.AGLOBL = AGLOBL,
|
|
||||||
.AJMP = ABR,
|
|
||||||
.ANOP = ANOP,
|
|
||||||
.APCDATA = APCDATA,
|
|
||||||
.ARET = ARETURN,
|
|
||||||
.ATEXT = ATEXT,
|
|
||||||
.ATYPE = ATYPE,
|
|
||||||
.AUSEFIELD = AUSEFIELD,
|
|
||||||
};
|
};
|
||||||
|
@ -147,10 +147,10 @@ writeobj(Link *ctxt, Biobuf *b)
|
|||||||
plink = p->link;
|
plink = p->link;
|
||||||
p->link = nil;
|
p->link = nil;
|
||||||
|
|
||||||
if(p->as == ctxt->arch->AEND)
|
if(p->as == AEND)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(p->as == ctxt->arch->ATYPE) {
|
if(p->as == ATYPE) {
|
||||||
// Assume each TYPE instruction describes
|
// Assume each TYPE instruction describes
|
||||||
// a different local variable or parameter,
|
// a different local variable or parameter,
|
||||||
// so no dedup.
|
// so no dedup.
|
||||||
@ -174,7 +174,7 @@ writeobj(Link *ctxt, Biobuf *b)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p->as == ctxt->arch->AGLOBL) {
|
if(p->as == AGLOBL) {
|
||||||
s = p->from.sym;
|
s = p->from.sym;
|
||||||
if(s->seenglobl++)
|
if(s->seenglobl++)
|
||||||
print("duplicate %P\n", p);
|
print("duplicate %P\n", p);
|
||||||
@ -200,12 +200,12 @@ writeobj(Link *ctxt, Biobuf *b)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p->as == ctxt->arch->ADATA) {
|
if(p->as == ADATA) {
|
||||||
savedata(ctxt, p->from.sym, p, "<input>");
|
savedata(ctxt, p->from.sym, p, "<input>");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p->as == ctxt->arch->ATEXT) {
|
if(p->as == ATEXT) {
|
||||||
s = p->from.sym;
|
s = p->from.sym;
|
||||||
if(s == nil) {
|
if(s == nil) {
|
||||||
// func _() { }
|
// func _() { }
|
||||||
@ -235,7 +235,7 @@ writeobj(Link *ctxt, Biobuf *b)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p->as == ctxt->arch->AFUNCDATA) {
|
if(p->as == AFUNCDATA) {
|
||||||
// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
|
// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
|
||||||
if(curtext == nil) // func _() {}
|
if(curtext == nil) // func _() {}
|
||||||
continue;
|
continue;
|
||||||
@ -260,14 +260,14 @@ writeobj(Link *ctxt, Biobuf *b)
|
|||||||
continue;
|
continue;
|
||||||
found = 0;
|
found = 0;
|
||||||
for(p = s->text; p != nil; p = p->link) {
|
for(p = s->text; p != nil; p = p->link) {
|
||||||
if(p->as == ctxt->arch->AFUNCDATA && p->from.type == TYPE_CONST && p->from.offset == FUNCDATA_ArgsPointerMaps) {
|
if(p->as == AFUNCDATA && p->from.type == TYPE_CONST && p->from.offset == FUNCDATA_ArgsPointerMaps) {
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!found) {
|
if(!found) {
|
||||||
p = appendp(ctxt, s->text);
|
p = appendp(ctxt, s->text);
|
||||||
p->as = ctxt->arch->AFUNCDATA;
|
p->as = AFUNCDATA;
|
||||||
p->from.type = TYPE_CONST;
|
p->from.type = TYPE_CONST;
|
||||||
p->from.offset = FUNCDATA_ArgsPointerMaps;
|
p->from.offset = FUNCDATA_ArgsPointerMaps;
|
||||||
p->to.type = TYPE_MEM;
|
p->to.type = TYPE_MEM;
|
||||||
|
@ -40,8 +40,9 @@ brchain(Link *ctxt, Prog *p)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
USED(ctxt);
|
||||||
for(i=0; i<20; i++) {
|
for(i=0; i<20; i++) {
|
||||||
if(p == nil || p->as != ctxt->arch->AJMP || p->pcond == nil)
|
if(p == nil || p->as != AJMP || p->pcond == nil)
|
||||||
return p;
|
return p;
|
||||||
p = p->pcond;
|
p = p->pcond;
|
||||||
}
|
}
|
||||||
@ -54,9 +55,10 @@ brloop(Link *ctxt, Prog *p)
|
|||||||
int c;
|
int c;
|
||||||
Prog *q;
|
Prog *q;
|
||||||
|
|
||||||
|
USED(ctxt);
|
||||||
c = 0;
|
c = 0;
|
||||||
for(q = p; q != nil; q = q->pcond) {
|
for(q = p; q != nil; q = q->pcond) {
|
||||||
if(q->as != ctxt->arch->AJMP || q->pcond == nil)
|
if(q->as != AJMP || q->pcond == nil)
|
||||||
break;
|
break;
|
||||||
c++;
|
c++;
|
||||||
if(c >= 5000)
|
if(c >= 5000)
|
||||||
|
@ -160,7 +160,7 @@ pctofileline(Link *ctxt, LSym *sym, int32 oldval, Prog *p, int32 phase, void *ar
|
|||||||
|
|
||||||
USED(sym);
|
USED(sym);
|
||||||
|
|
||||||
if(p->as == ctxt->arch->ATEXT || p->as == ctxt->arch->ANOP || p->as == ctxt->arch->AUSEFIELD || p->lineno == 0 || phase == 1)
|
if(p->as == ATEXT || p->as == ANOP || p->as == AUSEFIELD || p->lineno == 0 || phase == 1)
|
||||||
return oldval;
|
return oldval;
|
||||||
linkgetline(ctxt, p->lineno, &f, &l);
|
linkgetline(ctxt, p->lineno, &f, &l);
|
||||||
if(f == nil) {
|
if(f == nil) {
|
||||||
@ -223,7 +223,7 @@ pctopcdata(Link *ctxt, LSym *sym, int32 oldval, Prog *p, int32 phase, void *arg)
|
|||||||
{
|
{
|
||||||
USED(sym);
|
USED(sym);
|
||||||
|
|
||||||
if(phase == 0 || p->as != ctxt->arch->APCDATA || p->from.offset != (uintptr)arg)
|
if(phase == 0 || p->as != APCDATA || p->from.offset != (uintptr)arg)
|
||||||
return oldval;
|
return oldval;
|
||||||
if((int32)p->to.offset != p->to.offset) {
|
if((int32)p->to.offset != p->to.offset) {
|
||||||
ctxt->diag("overflow in PCDATA instruction: %P", p);
|
ctxt->diag("overflow in PCDATA instruction: %P", p);
|
||||||
@ -248,9 +248,9 @@ linkpcln(Link *ctxt, LSym *cursym)
|
|||||||
npcdata = 0;
|
npcdata = 0;
|
||||||
nfuncdata = 0;
|
nfuncdata = 0;
|
||||||
for(p = cursym->text; p != nil; p = p->link) {
|
for(p = cursym->text; p != nil; p = p->link) {
|
||||||
if(p->as == ctxt->arch->APCDATA && p->from.offset >= npcdata)
|
if(p->as == APCDATA && p->from.offset >= npcdata)
|
||||||
npcdata = p->from.offset+1;
|
npcdata = p->from.offset+1;
|
||||||
if(p->as == ctxt->arch->AFUNCDATA && p->from.offset >= nfuncdata)
|
if(p->as == AFUNCDATA && p->from.offset >= nfuncdata)
|
||||||
nfuncdata = p->from.offset+1;
|
nfuncdata = p->from.offset+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,12 +269,12 @@ linkpcln(Link *ctxt, LSym *cursym)
|
|||||||
havepc = emallocz(n);
|
havepc = emallocz(n);
|
||||||
havefunc = havepc + (npcdata+31)/32;
|
havefunc = havepc + (npcdata+31)/32;
|
||||||
for(p = cursym->text; p != nil; p = p->link) {
|
for(p = cursym->text; p != nil; p = p->link) {
|
||||||
if(p->as == ctxt->arch->AFUNCDATA) {
|
if(p->as == AFUNCDATA) {
|
||||||
if((havefunc[p->from.offset/32]>>(p->from.offset%32))&1)
|
if((havefunc[p->from.offset/32]>>(p->from.offset%32))&1)
|
||||||
ctxt->diag("multiple definitions for FUNCDATA $%d", p->from.offset);
|
ctxt->diag("multiple definitions for FUNCDATA $%d", p->from.offset);
|
||||||
havefunc[p->from.offset/32] |= 1<<(p->from.offset%32);
|
havefunc[p->from.offset/32] |= 1<<(p->from.offset%32);
|
||||||
}
|
}
|
||||||
if(p->as == ctxt->arch->APCDATA)
|
if(p->as == APCDATA)
|
||||||
havepc[p->from.offset/32] |= 1<<(p->from.offset%32);
|
havepc[p->from.offset/32] |= 1<<(p->from.offset%32);
|
||||||
}
|
}
|
||||||
// pcdata.
|
// pcdata.
|
||||||
@ -288,7 +288,7 @@ linkpcln(Link *ctxt, LSym *cursym)
|
|||||||
// funcdata
|
// funcdata
|
||||||
if(nfuncdata > 0) {
|
if(nfuncdata > 0) {
|
||||||
for(p = cursym->text; p != nil; p = p->link) {
|
for(p = cursym->text; p != nil; p = p->link) {
|
||||||
if(p->as == ctxt->arch->AFUNCDATA) {
|
if(p->as == AFUNCDATA) {
|
||||||
i = p->from.offset;
|
i = p->from.offset;
|
||||||
pcln->funcdataoff[i] = p->to.offset;
|
pcln->funcdataoff[i] = p->to.offset;
|
||||||
if(p->to.type != TYPE_CONST) {
|
if(p->to.type != TYPE_CONST) {
|
||||||
|
Loading…
Reference in New Issue
Block a user