Commit 4be75c8f authored by Shenghou Ma's avatar Shenghou Ma

[dev.power64] include/link.h, liblink: convert 9l functions to liblink

This replaces CL 122990043.

LGTM=rsc
R=rsc, iant
CC=golang-codereviews
https://golang.org/cl/123010043
parent 7c33e507
......@@ -62,9 +62,9 @@ struct Addr
short type;
uint8 index;
int8 scale;
int8 reg; // for 5l
int8 name; // for 5l
int8 class; // for 5l
int8 reg; // for 5l, 9l
int8 name; // for 5l, 9l
int8 class; // for 5l, 9l
uint8 etype; // for 5g, 6g, 8g
int32 offset2; // for 5l, 8l
struct Node* node; // for 5g, 6g, 8g
......@@ -89,9 +89,10 @@ struct Prog
int32 lineno;
Prog* link;
short as;
uchar reg; // arm only
uchar reg; // arm, power64 only
uchar scond; // arm only
Addr from;
Addr from3; // power64 only, fma and rlwm
Addr to;
// for 5g, 6g, 8g internal use
......@@ -103,11 +104,11 @@ struct Prog
Prog* comefrom; // 6l, 8l
Prog* pcrel; // 5l
int32 spadj;
uchar mark;
uint16 mark;
uint16 optab; // 5l, 9l
uchar back; // 6l, 8l
uchar ft; /* 6l, 8l oclass cache */
uchar tt; // 6l, 8l
uint16 optab; // 5l
uchar isize; // 6l, 8l
char width; /* fake for DATA */
......@@ -232,10 +233,12 @@ enum
enum
{
R_ADDR = 1,
R_ADDRPOWER, // relocation for loading 31-bit address using addis and addi/ld/st for Power
R_SIZE,
R_CALL, // relocation for direct PC-relative call
R_CALLARM, // relocation for ARM direct call
R_CALLIND, // marker for indirect call (no actual relocating necessary)
R_CALLPOWER, // relocation for Power direct call
R_CONST,
R_PCREL,
R_TLS,
......@@ -526,6 +529,9 @@ void span6(Link *ctxt, LSym *s);
// asm8.c
void span8(Link *ctxt, LSym *s);
// asm9.c
void span9(Link *ctxt, LSym *s);
// data.c
vlong addaddr(Link *ctxt, LSym *s, LSym *t);
vlong addaddrplus(Link *ctxt, LSym *s, LSym *t, vlong add);
......@@ -572,10 +578,11 @@ Prog* copyp(Link*, Prog*);
Prog* appendp(Link*, Prog*);
vlong atolwhex(char*);
// list[568].c
// list[5689].c
void listinit5(void);
void listinit6(void);
void listinit8(void);
void listinit9(void);
// obj.c
int linklinefmt(Link *ctxt, Fmt *fp);
......@@ -607,20 +614,24 @@ char* headstr(int);
extern char* anames5[];
extern char* anames6[];
extern char* anames8[];
extern char* anames9[];
extern char* cnames5[];
extern char* cnames9[];
extern LinkArch link386;
extern LinkArch linkamd64;
extern LinkArch linkamd64p32;
extern LinkArch linkarm;
extern LinkArch linkpower64;
extern LinkArch linkpower64le;
#pragma varargck type "A" int
#pragma varargck type "D" Addr*
#pragma varargck type "lD" Addr*
#pragma varargck type "P" Prog*
#pragma varargck type "R" int
#pragma varargck type "^" int
#pragma varargck type "^" int // for 5l/9l, C_* classes (liblink internal)
// TODO(ality): remove this workaround.
// It's here because Pconv in liblink/list?.c references %L.
......
This diff is collapsed.
......@@ -27,29 +27,61 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// +build ignore
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <link.h>
#include "../cmd/9l/9.out.h"
#include "l.h"
enum
{
STRINGSZ = 1000,
};
static int Aconv(Fmt*);
static int Dconv(Fmt*);
static int Pconv(Fmt*);
static int Rconv(Fmt*);
static int DSconv(Fmt*);
static int Mconv(Fmt*);
static int DRconv(Fmt*);
//
// Format conversions
// %A int Opcodes (instruction mnemonics)
//
// %D Addr* Addresses (instruction operands)
// Flags: "%lD": seperate the high and low words of a constant by "-"
//
// %P Prog* Instructions
//
// %R int Registers
//
// %$ char* String constant addresses (for internal use only)
// %^ int C_* classes (for liblink internal use)
#pragma varargck type "$" char*
#pragma varargck type "M" Addr*
void
listinit(void)
listinit9(void)
{
fmtinstall('A', Aconv);
fmtinstall('D', Dconv);
fmtinstall('P', Pconv);
fmtinstall('S', Sconv);
fmtinstall('N', Nconv);
fmtinstall('R', Rconv);
}
void
prasm(Prog *p)
{
print("%P\n", p);
// for liblink internal use
fmtinstall('^', DRconv);
// for internal use
fmtinstall('$', DSconv);
fmtinstall('M', Mconv);
}
int
static Prog* bigP;
static int
Pconv(Fmt *fp)
{
char str[STRINGSZ], *s;
......@@ -57,26 +89,36 @@ Pconv(Fmt *fp)
int a;
p = va_arg(fp->args, Prog*);
curp = p;
bigP = p;
a = p->as;
if(a == ADATA || a == AINIT || a == ADYNT)
sprint(str, "(%d) %A %D/%d,%D", p->line, a, &p->from, p->reg, &p->to);
else {
sprint(str, "%.5lld (%L) %A %D/%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
else if(a == ATEXT) {
if(p->reg != 0)
sprint(str, "%.5lld (%L) %A %D,%d,%lD", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
else
sprint(str, "%.5lld (%L) %A %D,%lD", p->pc, p->lineno, a, &p->from, &p->to);
} else if(a == AGLOBL) {
if(p->reg != 0)
sprint(str, "%.5lld (%L) %A %D,%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
else
sprint(str, "%.5lld (%L) %A %D,%D", p->pc, p->lineno, a, &p->from, &p->to);
} else {
s = str;
if(p->mark & NOSCHED)
s += sprint(s, "*");
if(p->reg == NREG && p->from3.type == D_NONE)
sprint(s, "(%d) %A %D,%D", p->line, a, &p->from, &p->to);
sprint(s, "%.5lld (%d) %A %D,%D", p->pc, p->lineno, a, &p->from, &p->to);
else
if(a != ATEXT && p->from.type == D_OREG) {
sprint(s, "(%d) %A %lld(R%d+R%d),%D", p->line, a,
sprint(s, "%.5lld (%d) %A %lld(R%d+R%d),%D", p->pc, p->lineno, a,
p->from.offset, p->from.reg, p->reg, &p->to);
} else
if(p->to.type == D_OREG) {
sprint(s, "(%d) %A %D,%lld(R%d+R%d)", p->line, a,
sprint(s, "%.5lld (%d) %A %D,%lld(R%d+R%d)", p->pc, p->lineno, a,
&p->from, p->to.offset, p->to.reg, p->reg);
} else {
s += sprint(s, "(%d) %A %D", p->line, a, &p->from);
s += sprint(s, "%.5lld (%L) %A %D", p->pc, p->lineno, a, &p->from);
if(p->reg != NREG)
s += sprint(s, ",%c%d", p->from.type==D_FREG?'F':'R', p->reg);
if(p->from3.type != D_NONE)
......@@ -87,7 +129,7 @@ Pconv(Fmt *fp)
return fmtstrcpy(fp, str);
}
int
static int
Aconv(Fmt *fp)
{
char *s;
......@@ -96,55 +138,65 @@ Aconv(Fmt *fp)
a = va_arg(fp->args, int);
s = "???";
if(a >= AXXX && a < ALAST)
s = anames[a];
s = anames9[a];
return fmtstrcpy(fp, s);
}
int
static int
Dconv(Fmt *fp)
{
char str[STRINGSZ];
Adr *a;
long v;
Addr *a;
int32 v;
a = va_arg(fp->args, Adr*);
switch(a->type) {
a = va_arg(fp->args, Addr*);
if(fp->flags & FmtLong) {
if(a->type == D_CONST)
sprint(str, "$%d-%d", (int32)a->offset, (int32)(a->offset>>32));
else {
// ATEXT dst is not constant
sprint(str, "!!%D", a);
}
goto ret;
}
switch(a->type) {
default:
sprint(str, "GOK-type(%d)", a->type);
break;
case D_NONE:
str[0] = 0;
if(a->name != D_NONE || a->reg != NREG || a->sym != S)
sprint(str, "%N(R%d)(NONE)", a, a->reg);
if(a->name != D_NONE || a->reg != NREG || a->sym != nil)
sprint(str, "%M(R%d)(NONE)", a, a->reg);
break;
case D_CONST:
case D_DCONST:
if(a->reg != NREG)
sprint(str, "$%N(R%d)", a, a->reg);
sprint(str, "$%M(R%d)", a, a->reg);
else
sprint(str, "$%N", a);
sprint(str, "$%M", a);
break;
case D_OREG:
if(a->reg != NREG)
sprint(str, "%N(R%d)", a, a->reg);
sprint(str, "%M(R%d)", a, a->reg);
else
sprint(str, "%N", a);
sprint(str, "%M", a);
break;
case D_REG:
sprint(str, "R%d", a->reg);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%N(R%d)(REG)", a, a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(R%d)(REG)", a, a->reg);
break;
case D_FREG:
sprint(str, "F%d", a->reg);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%N(F%d)(REG)", a, a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(F%d)(REG)", a, a->reg);
break;
case D_CREG:
......@@ -152,12 +204,12 @@ Dconv(Fmt *fp)
strcpy(str, "CR");
else
sprint(str, "CR%d", a->reg);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%N(C%d)(REG)", a, a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(C%d)(REG)", a, a->reg);
break;
case D_SPR:
if(a->name == D_NONE && a->sym == S) {
if(a->name == D_NONE && a->sym == nil) {
switch((ulong)a->offset) {
case D_XER: sprint(str, "XER"); break;
case D_LR: sprint(str, "LR"); break;
......@@ -167,18 +219,18 @@ Dconv(Fmt *fp)
break;
}
sprint(str, "SPR-GOK(%d)", a->reg);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%N(SPR-GOK%d)(REG)", a, a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(SPR-GOK%d)(REG)", a, a->reg);
break;
case D_DCR:
if(a->name == D_NONE && a->sym == S) {
if(a->name == D_NONE && a->sym == nil) {
sprint(str, "DCR(%lld)", a->offset);
break;
}
sprint(str, "DCR-GOK(%d)", a->reg);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%N(DCR-GOK%d)(REG)", a, a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(DCR-GOK%d)(REG)", a, a->reg);
break;
case D_OPT:
......@@ -197,57 +249,71 @@ Dconv(Fmt *fp)
break;
case D_BRANCH:
if(curp->cond != P) {
v = curp->cond->pc;
if(v >= INITTEXT)
v -= INITTEXT-HEADR;
if(a->sym != S)
if(bigP->pcond != nil) {
v = bigP->pcond->pc;
//if(v >= INITTEXT)
// v -= INITTEXT-HEADR;
if(a->sym != nil)
sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
else
sprint(str, "%.5lux(BRANCH)", v);
} else
if(a->sym != S)
if(a->sym != nil)
sprint(str, "%s+%lld(APC)", a->sym->name, a->offset);
else
sprint(str, "%lld(APC)", a->offset);
break;
case D_FCONST:
sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
//sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
sprint(str, "$%.17g", a->u.dval);
break;
case D_SCONST:
sprint(str, "$\"%S\"", a->sval);
sprint(str, "$\"%$\"", a->u.sval);
break;
}
ret:
return fmtstrcpy(fp, str);
}
int
Nconv(Fmt *fp)
static int
Mconv(Fmt *fp)
{
char str[STRINGSZ];
Adr *a;
Sym *s;
long l;
Addr *a;
LSym *s;
int32 l;
a = va_arg(fp->args, Adr*);
a = va_arg(fp->args, Addr*);
s = a->sym;
if(s == S) {
//if(s == nil) {
// l = a->offset;
// if((vlong)l != a->offset)
// sprint(str, "0x%llux", a->offset);
// else
// sprint(str, "%lld", a->offset);
// goto out;
//}
switch(a->name) {
default:
sprint(str, "GOK-name(%d)", a->name);
break;
case D_NONE:
l = a->offset;
if((vlong)l != a->offset)
sprint(str, "0x%llux", a->offset);
else
sprint(str, "%lld", a->offset);
goto out;
}
switch(a->name) {
default:
sprint(str, "GOK-name(%d)", a->name);
break;
case D_EXTERN:
sprint(str, "%s+%lld(SB)", s->name, a->offset);
if(a->offset != 0)
sprint(str, "%s+%lld(SB)", s->name, a->offset);
else
sprint(str, "%s(SB)", s->name, a->offset);
break;
case D_STATIC:
......@@ -255,19 +321,36 @@ Nconv(Fmt *fp)
break;
case D_AUTO:
sprint(str, "%s-%lld(SP)", s->name, -a->offset);
if(s == nil)
sprint(str, "%lld(SP)", -a->offset);
else
sprint(str, "%s-%lld(SP)", s->name, -a->offset);
break;
case D_PARAM:
sprint(str, "%s+%lld(FP)", s->name, a->offset);
if(s == nil)
sprint(str, "%lld(FP)", a->offset);
else
sprint(str, "%s+%lld(FP)", s->name, a->offset);
break;
}
out:
//out:
return fmtstrcpy(fp, str);
}
int
static int
Rconv(Fmt *fp)
{
char str[STRINGSZ];
int r;
r = va_arg(fp->args, int);
sprint(str, "r%d", r);
return fmtstrcpy(fp, str);
}
static int
DRconv(Fmt *fp)
{
char *s;
int a;
......@@ -275,19 +358,19 @@ Rconv(Fmt *fp)
a = va_arg(fp->args, int);
s = "C_??";
if(a >= C_NONE && a <= C_NCLASS)
s = cnames[a];
s = cnames9[a];
return fmtstrcpy(fp, s);
}
int
Sconv(Fmt *fp)
static int
DSconv(Fmt *fp)
{
int i, c;
char str[STRINGSZ], *p, *a;
a = va_arg(fp->args, char*);
p = str;
for(i=0; i<sizeof(long); i++) {
for(i=0; i<sizeof(int32); i++) {
c = a[i] & 0xff;
if(c >= 'a' && c <= 'z' ||
c >= 'A' && c <= 'Z' ||
......@@ -319,24 +402,3 @@ Sconv(Fmt *fp)
*p = 0;
return fmtstrcpy(fp, str);
}
void
diag(char *fmt, ...)
{
char buf[STRINGSZ], *tn;
va_list arg;
tn = "??none??";
if(curtext != P && curtext->from.sym != S)
tn = curtext->from.sym->name;
va_start(arg, fmt);
vseprint(buf, buf+sizeof(buf), fmt, arg);
va_end(arg);
print("%s: %s\n", tn, buf);
nerrors++;
if(nerrors > 10) {
print("too many errors\n");
errorexit();
}
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment