ref: 7a7dfee4fab3e9a725422edff93251ef0a717492
dir: /libinterp/das-sparc.c/
#include <lib9.h>
/* Sparc disassembler and related functions */
typedef struct instr Instr;
struct opcode
{
char *mnemonic;
void (*f)(Instr*, char*);
int flag;
};
static char FRAMENAME[] = ".frame";
struct instr
{
uchar op; /* bits 31-30 */
uchar rd; /* bits 29-25 */
uchar op2; /* bits 24-22 */
uchar a; /* bit 29 */
uchar cond; /* bits 28-25 */
uchar op3; /* bits 24-19 */
uchar rs1; /* bits 18-14 */
uchar i; /* bit 13 */
uchar asi; /* bits 12-05 */
uchar rs2; /* bits 04-00 */
short simm13; /* bits 12-00, signed */
ushort opf; /* bits 13-05 */
ulong immdisp22; /* bits 21-00 */
ulong simmdisp22; /* bits 21-00, signed */
ulong disp30; /* bits 30-00 */
ulong imm32; /* SETHI+ADD constant */
int target; /* SETHI+ADD dest reg */
long w0;
long w1;
ulong addr; /* pc of instruction */
char* curr; /* current fill level in output buffer */
char* end; /* end of buffer */
int size; /* number of longs in instr */
char* err; /* errmsg */
};
static int dascase;
static int mkinstr(ulong*, Instr*);
static void bra1(Instr*, char*, char*[]);
static void bra(Instr*, char*);
static void fbra(Instr*, char*);
static void cbra(Instr*, char*);
static void unimp(Instr*, char*);
static void fpop(Instr*, char*);
static void shift(Instr*, char*);
static void sethi(Instr*, char*);
static void load(Instr*, char*);
static void loada(Instr*, char*);
static void store(Instr*, char*);
static void storea(Instr*, char*);
static void add(Instr*, char*);
static void cmp(Instr*, char*);
static void wr(Instr*, char*);
static void jmpl(Instr*, char*);
static void rd(Instr*, char*);
static void loadf(Instr*, char*);
static void storef(Instr*, char*);
static void loadc(Instr*, char*);
static void loadcsr(Instr*, char*);
static void trap(Instr*, char*);
static struct opcode sparcop0[8] = {
/* [0] */ "UNIMP", unimp, 0, /* page 137 */
0, 0, 0,
/* [2] */ "B", bra, 0, /* page 119 */
0, 0, 0,
/* [4] */ "SETHI", sethi, 0, /* page 104 */
0, 0, 0,
/* [6] */ "FB", fbra, 0, /* page 121 */
/* [7] */ "CB", cbra, 0, /* page 123 */
};
static struct opcode sparcop2[64] = {
/* [0x00] */ "ADD", add, 0, /* page 108 */
/* [0x01] */ "AND", add, 0, /* page 106 */
/* [0x02] */ "OR", add, 0,
/* [0x03] */ "XOR", add, 0,
/* [0x04] */ "SUB", add, 0, /* page 110 */
/* [0x05] */ "ANDN", add, 0,
/* [0x06] */ "ORN", add, 0,
/* [0x07] */ "XORN", add, 0,
/* [0x08] */ "ADDX", add, 0,
0, 0, 0,
/* [0x0A] */ "UMUL", add, 0, /* page 113 */
/* [0x0B] */ "SMUL", add, 0,
/* [0x0C] */ "SUBX", add, 0,
0, 0, 0,
/* [0x0E] */ "UDIV", add, 0, /* page 115 */
/* [0x0F] */ "SDIV", add, 0,
/* [0x10] */ "ADDCC", add, 0,
/* [0x11] */ "ANDCC", add, 0,
/* [0x12] */ "ORCC", add, 0,
/* [0x13] */ "XORCC", add, 0,
/* [0x14] */ "SUBCC", cmp, 0,
/* [0x15] */ "ANDNCC", add, 0,
/* [0x16] */ "ORNCC", add, 0,
/* [0x17] */ "XORNCC", add, 0,
/* [0x18] */ "ADDXCC", add, 0,
0, 0, 0,
/* [0x1A] */ "UMULCC", add, 0,
/* [0x1B] */ "SMULCC", add, 0,
/* [0x1C] */ "SUBXCC", add, 0,
0, 0, 0,
/* [0x1E] */ "UDIVCC", add, 0,
/* [0x1F] */ "SDIVCC", add, 0,
/* [0x20] */ "TADD", add, 0, /* page 109 */
/* [0x21] */ "TSUB", add, 0, /* page 111 */
/* [0x22] */ "TADDCCTV", add, 0,
/* [0x23] */ "TSUBCCTV", add, 0,
/* [0x24] */ "MULSCC", add, 0, /* page 112 */
/* [0x25] */ "SLL", shift, 0, /* page 107 */
/* [0x26] */ "SRL", shift, 0,
/* [0x27] */ "SRA", shift, 0,
/* [0x28] */ "rdy", rd, 0, /* page 131 */
/* [0x29] */ "rdpsr", rd, 0,
/* [0x2A] */ "rdwim", rd, 0,
/* [0x2B] */ "rdtbr", rd, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
/* [0x30] */ "wry", wr, 0, /* page 133 */
/* [0x31] */ "wrpsr", wr, 0,
/* [0x32] */ "wrwim", wr, 0,
/* [0x33] */ "wrtbr", wr, 0,
/* [0x34] */ "FPOP", fpop, 0, /* page 140 */
/* [0x35] */ "FPOP", fpop, 0,
0, 0, 0,
0, 0, 0,
/* [0x38] */ "JMPL", jmpl, 0, /* page 126 */
/* [0x39] */ "RETT", add, 0, /* page 127 */
/* [0x3A] */ "T", trap, 0, /* page 129 */
/* [0x3B] */ "flush", add, 0, /* page 138 */
/* [0x3C] */ "SAVE", add, 0, /* page 117 */
/* [0x3D] */ "RESTORE", add, 0,
};
static struct opcode sparcop3[64]={
/* [0x00] */ "ld", load, 0,
/* [0x01] */ "ldub", load, 0,
/* [0x02] */ "lduh", load, 0,
/* [0x03] */ "ldd", load, 0,
/* [0x04] */ "st", store, 0,
/* [0x05] */ "stb", store, 0, /* page 95 */
/* [0x06] */ "sth", store, 0,
/* [0x07] */ "std", store, 0,
0, 0, 0,
/* [0x09] */ "ldsb", load, 0, /* page 90 */
/* [0x0A] */ "ldsh", load, 0,
0, 0, 0,
0, 0, 0,
/* [0x0D] */ "ldstub", store, 0, /* page 101 */
0, 0, 0,
/* [0x0F] */ "swap", load, 0, /* page 102 */
/* [0x10] */ "lda", loada, 0,
/* [0x11] */ "lduba", loada, 0,
/* [0x12] */ "lduha", loada, 0,
/* [0x13] */ "ldda", loada, 0,
/* [0x14] */ "sta", storea, 0,
/* [0x15] */ "stba", storea, 0,
/* [0x16] */ "stha", storea, 0,
/* [0x17] */ "stda", storea, 0,
0, 0, 0,
/* [0x19] */ "ldsba", loada, 0,
/* [0x1A] */ "ldsha", loada, 0,
0, 0, 0,
0, 0, 0,
/* [0x1D] */ "ldstuba", storea, 0,
0, 0, 0,
/* [0x1F] */ "swapa", loada, 0,
/* [0x20] */ "ldf", loadf, 0, /* page 92 */
/* [0x21] */ "ldfsr", loadf, 0,
0, 0, 0,
/* [0x23] */ "lddf", loadf, 0,
/* [0x24] */ "stf", storef, 0, /* page 97 */
/* [0x25] */ "stfsr", storef, 0,
/* [0x26] */ "stdfq", storef, 0,
/* [0x27] */ "stdf", storef, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
/* [0x30] */ "ldc", loadc, 0, /* page 94 */
/* [0x31] */ "ldcsr", loadcsr,0,
0, 0, 0,
/* [0x33] */ "lddc", loadc, 0,
/* [0x34] */ "stc", loadc, 0, /* page 99 */
/* [0x35] */ "stcsr", loadcsr,0,
/* [0x36] */ "stdcq", loadcsr,0,
/* [0x37] */ "stdc", loadc, 0,
};
static void
bprint(Instr *i, char *fmt, ...)
{
va_list arg;
va_start(arg, fmt);
i->curr = vseprint(i->curr, i->end, fmt, arg);
va_end(arg);
}
static int
decode(ulong *pc, Instr *i)
{
ulong w;
w = *pc;
i->op = (w >> 30) & 0x03;
i->rd = (w >> 25) & 0x1F;
i->op2 = (w >> 22) & 0x07;
i->a = (w >> 29) & 0x01;
i->cond = (w >> 25) & 0x0F;
i->op3 = (w >> 19) & 0x3F;
i->rs1 = (w >> 14) & 0x1F;
i->i = (w >> 13) & 0x01;
i->asi = (w >> 5) & 0xFF;
i->rs2 = (w >> 0) & 0x1F;
i->simm13 = (w >> 0) & 0x1FFF;
if(i->simm13 & (1<<12))
i->simm13 |= ~((1<<13)-1);
i->opf = (w >> 5) & 0x1FF;
i->immdisp22 = (w >> 0) & 0x3FFFFF;
i->simmdisp22 = i->immdisp22;
if(i->simmdisp22 & (1<<21))
i->simmdisp22 |= ~((1<<22)-1);
i->disp30 = (w >> 0) & 0x3FFFFFFF;
i->w0 = w;
i->target = -1;
i->addr = (ulong)pc;
i->size = 1;
return 1;
}
static int
mkinstr(ulong *pc, Instr *i)
{
Instr xi;
if (decode(pc, i) < 0)
return -1;
if(i->op==0 && i->op2==4 && !dascase){ /* SETHI */
if(decode(pc+1, &xi) < 0)
return -1;
if(xi.op == 2 && xi.op3 == 0) /* ADD */
if(xi.i == 1 && xi.rs1 == i->rd){ /* immediate to same reg */
i->imm32 = xi.simm13 + (i->immdisp22<<10);
i->target = xi.rd;
i->w1 = xi.w0;
i->size++;
return 1;
}
}
if(i->op==2 && i->opf==1 && !dascase){ /* FMOVS */
if (decode(pc+1, &xi) < 0)
return -1;
if(i->op==2 && i->opf==1) /* FMOVS */
if(xi.rd==i->rd+1 && xi.rs2==i->rs2+1){ /* next pair */
i->w1 = xi.w0;
i->size++;
}
}
return 1;
}
static int
inst(ulong *pc)
{
long disp;
Instr instr;
static char buf[128];
void (*f)(Instr*, char*);
memset(&instr, 0, sizeof(instr));
instr.curr = buf;
instr.end = buf+sizeof(buf)-1;
if(mkinstr(pc, &instr) < 0)
return 4;
switch(instr.op){
case 0:
f = sparcop0[instr.op2].f;
if(f)
(*f)(&instr, sparcop0[instr.op2].mnemonic);
else
bprint(&instr, "unknown 0x%lux", instr.w0);
break;
case 1:
disp = instr.disp30;
disp = (disp<<2)>>2;
bprint(&instr, "CALL\t0x%lux", pc+disp);
if (!dascase)
bprint(&instr, "(SB)");
break;
case 2:
f = sparcop2[instr.op3].f;
if(f)
(*f)(&instr, sparcop2[instr.op3].mnemonic);
else
bprint(&instr, "unknown 0x%lux", instr.w0);
break;
case 3:
f = sparcop3[instr.op3].f;
if(f)
(*f)(&instr, sparcop3[instr.op3].mnemonic);
else
bprint(&instr, "unknown 0x%lux", instr.w0);
break;
}
if (instr.err) {
if (instr.curr != buf)
bprint(&instr, "\t\t;");
bprint(&instr, instr.err);
}
print("\t%.8lux %s\n", (ulong)pc, buf);
return instr.size;
}
void
das(ulong *pc, int n)
{
ulong *e;
e = pc + n;
while(pc < e)
pc += inst(pc);
}
static void
address(Instr *i)
{
bprint(i, "0x%lux(R%d)", i->simm13, i->rs1);
}
static void
unimp(Instr *i, char *m)
{
bprint(i, "%s", m);
}
static char *bratab[16] = { /* page 91 */
/* [0x0] */ "N",
/* [0x1] */ "E",
/* [0x2] */ "LE",
/* [0x3] */ "L",
/* [0x4] */ "LEU",
/* [0x5] */ "CS",
/* [0x6] */ "NEG",
/* [0x7] */ "VS",
/* [0x8] */ "A",
/* [0x9] */ "NE",
/* [0xA] */ "G",
/* [0xB] */ "GE",
/* [0xC] */ "GU",
/* [0xD] */ "CC",
/* [0xE] */ "POS",
/* [0xF] */ "VC",
};
static char *fbratab[16] = { /* page 91 */
/* [0x0] */ "N",
/* [0x1] */ "NE",
/* [0x2] */ "LG",
/* [0x3] */ "UL",
/* [0x4] */ "L",
/* [0x5] */ "UG",
/* [0x6] */ "G",
/* [0x7] */ "U",
/* [0x8] */ "A",
/* [0x9] */ "E",
/* [0xA] */ "UE",
/* [0xB] */ "GE",
/* [0xC] */ "UGE",
/* [0xD] */ "LE",
/* [0xE] */ "ULE",
/* [0xF] */ "O",
};
static char *cbratab[16] = { /* page 91 */
/* [0x0] */ "N",
/* [0x1] */ "123",
/* [0x2] */ "12",
/* [0x3] */ "13",
/* [0x4] */ "1",
/* [0x5] */ "23",
/* [0x6] */ "2",
/* [0x7] */ "3",
/* [0x8] */ "A",
/* [0x9] */ "0",
/* [0xA] */ "03",
/* [0xB] */ "02",
/* [0xC] */ "023",
/* [0xD] */ "01",
/* [0xE] */ "013",
/* [0xF] */ "012",
};
static void
bra1(Instr *i, char *m, char *tab[])
{
long imm;
imm = i->simmdisp22;
if(i->a)
bprint(i, "%s%s.%c\t", m, tab[i->cond], 'A'+dascase);
else
bprint(i, "%s%s\t", m, tab[i->cond]);
bprint(i, "0x%lux", i->addr+4*imm);
if (!dascase)
bprint(i, "(SB)");
}
static void
bra(Instr *i, char *m) /* page 91 */
{
bra1(i, m, bratab);
}
static void
fbra(Instr *i, char *m) /* page 93 */
{
bra1(i, m, fbratab);
}
static void
cbra(Instr *i, char *m) /* page 95 */
{
bra1(i, m, cbratab);
}
static void
trap(Instr *i, char *m) /* page 101 */
{
if(i->i == 0)
bprint(i, "%s%s\tR%d+R%d", m, bratab[i->cond], i->rs2, i->rs1);
else
bprint(i, "%s%s\t$0x%lux+R%d", m, bratab[i->cond], i->simm13, i->rs1);
}
static void
sethi(Instr *i, char *m) /* page 89 */
{
ulong imm;
imm = i->immdisp22<<10;
if(dascase){
bprint(i, "%s\t0x%lux, R%d", m, imm, i->rd);
return;
}
if(imm==0 && i->rd==0){
bprint(i, "NOP");
return;
}
if(i->target < 0){
bprint(i, "MOVW\t$0x%lux, R%d", imm, i->rd);
return;
}
bprint(i, "MOVW\t$0x%lux, R%d", i->imm32, i->target);
}
static char ldtab[] = {
'W',
'B',
'H',
'D',
};
static char*
moveinstr(int op3, char *m)
{
char *s;
int c;
static char buf[8];
if(!dascase){
/* batshit cases */
if(op3 == 0xF || op3 == 0x1F)
return "SWAP";
if(op3 == 0xD || op3 == 0x1D)
return "TAS"; /* really LDSTUB */
c = ldtab[op3&3];
s = "";
if((op3&11)==1 || (op3&11)==2)
s="U";
sprint(buf, "MOV%c%s", c, s);
return buf;
}
return m;
}
static void
load(Instr *i, char *m) /* page 68 */
{
m = moveinstr(i->op3, m);
if(i->i == 0)
bprint(i, "%s\t(R%d+R%d), R%d", m, i->rs1, i->rs2, i->rd);
else{
bprint(i, "%s\t", m);
address(i);
bprint(i, ", R%d", i->rd);
}
}
static void
loada(Instr *i, char *m) /* page 68 */
{
m = moveinstr(i->op3, m);
if(i->i == 0)
bprint(i, "%s\t(R%d+R%d, %d), R%d", m, i->rs1, i->rs2, i->asi, i->rd);
else
bprint(i, "unknown ld asi 0x%lux", i->w0);
}
static void
store(Instr *i, char *m) /* page 74 */
{
m = moveinstr(i->op3, m);
if(i->i == 0)
bprint(i, "%s\tR%d, (R%d+R%d)",
m, i->rd, i->rs1, i->rs2);
else{
bprint(i, "%s\tR%d, ", m, i->rd);
address(i);
}
}
static void
storea(Instr *i, char *m) /* page 74 */
{
m = moveinstr(i->op3, m);
if(i->i == 0)
bprint(i, "%s\tR%d, (R%d+R%d, %d)", m, i->rd, i->rs1, i->rs2, i->asi);
else
bprint(i, "%s\tR%d, %d(R%d, %d), ???", m, i->rd, i->simm13, i->rs1, i->asi);
}
static void
shift(Instr *i, char *m) /* page 88 */
{
if(i->i == 0){
if(i->rs1 == i->rd)
if(dascase)
bprint(i, "%s\tR%d, R%d", m, i->rs1, i->rs2);
else
bprint(i, "%s\tR%d, R%d", m, i->rs2, i->rs1);
else
if(dascase)
bprint(i, "%s\tR%d, R%d, R%d", m, i->rs1, i->rs2, i->rd);
else
bprint(i, "%s\tR%d, R%d, R%d", m, i->rs2, i->rs1, i->rd);
}else{
if(i->rs1 == i->rd)
if(dascase)
bprint(i, "%s\t$%d,R%d", m, i->simm13&0x1F, i->rs1);
else
bprint(i, "%s\tR%d, $%d", m, i->rs1, i->simm13&0x1F);
else
if(dascase)
bprint(i, "%s\tR%d, $%d, R%d",m,i->rs1,i->simm13&0x1F,i->rd);
else
bprint(i, "%s\t$%d, R%d, R%d",m,i->simm13&0x1F,i->rs1,i->rd);
}
}
static void
add(Instr *i, char *m) /* page 82 */
{
if(i->i == 0){
if(dascase)
bprint(i, "%s\tR%d, R%d", m, i->rs1, i->rs2);
else
if(i->op3==2 && i->rs1==0 && i->rd) /* OR R2, R0, R1 */
bprint(i, "MOVW\tR%d", i->rs2);
else
bprint(i, "%s\tR%d, R%d", m, i->rs2, i->rs1);
}else{
if(dascase)
bprint(i, "%s\tR%d, $0x%lux", m, i->rs1, i->simm13);
else
if(i->op3==0 && i->rd && i->rs1==0) /* ADD $x, R0, R1 */
bprint(i, "MOVW\t$0x%lux", i->simm13);
else if(i->op3==0 && i->rd && i->rs1==2){
/* ADD $x, R2, R1 -> MOVW $x(SB), R1 */
bprint(i, "MOVW\t$");
address(i);
} else
bprint(i, "%s\t$0x%lux, R%d", m, i->simm13, i->rs1);
}
if(i->rs1 != i->rd)
bprint(i, ", R%d", i->rd);
}
static void
cmp(Instr *i, char *m)
{
if(dascase || i->rd){
add(i, m);
return;
}
if(i->i == 0)
bprint(i, "CMP\tR%d, R%d", i->rs1, i->rs2);
else
bprint(i, "CMP\tR%d, $0x%lux", i->rs1, i->simm13);
}
static char *regtab[4] =
{
"Y",
"PSR",
"WIM",
"TBR",
};
static void
wr(Instr *i, char *m) /* page 82 */
{
if(dascase){
if(i->i == 0)
bprint(i, "%s\tR%d, R%d", m, i->rs1, i->rs2);
else
bprint(i, "%s\tR%d, $0x%lux", m, i->rs1, i->simm13);
}else{
if(i->i && i->simm13==0)
bprint(i, "MOVW\tR%d", i->rs1);
else if(i->i == 0)
bprint(i, "wr\tR%d, R%d", i->rs2, i->rs1);
else
bprint(i, "wr\t$0x%lux, R%d", i->simm13, i->rs1);
}
bprint(i, ", %s", regtab[i->op3&3]);
}
static void
rd(Instr *i, char *m) /* page 103 */
{
if(i->rs1==15 && i->rd==0){
m = "stbar";
if(!dascase)
m = "STBAR";
bprint(i, "%s", m);
}else{
if(!dascase)
m = "MOVW";
bprint(i, "%s\t%s, R%d", m, regtab[i->op3&3], i->rd);
}
}
static void
jmpl(Instr *i, char *m) /* page 82 */
{
if(i->i == 0){
if(i->rd == 15)
bprint(i, "CALL\t(R%d+R%d)", i->rs2, i->rs1);
else
bprint(i, "%s\t(R%d+R%d), R%d", m, i->rs2, i->rs1, i->rd);
}else{
if(!dascase && i->simm13==8 && i->rs1==15 && i->rd==0)
bprint(i, "RETURN");
else{
bprint(i, "%s\t", m);
address(i);
bprint(i, ", R%d", i->rd);
}
}
}
static void
loadf(Instr *i, char *m) /* page 70 */
{
if(!dascase){
m = "FMOVD";
if(i->op3 == 0x20)
m = "FMOVF";
else if(i->op3 == 0x21)
m = "MOVW";
}
if(i->i == 0)
bprint(i, "%s\t(R%d+R%d)", m, i->rs1, i->rs2);
else{
bprint(i, "%s\t", m);
address(i);
}
if(i->op3 == 0x21)
bprint(i, ", FSR");
else
bprint(i, ", R%d", i->rd);
}
static
void storef(Instr *i, char *m) /* page 70 */
{
if(!dascase){
m = "FMOVD";
if(i->op3 == 0x25 || i->op3 == 0x26)
m = "MOVW";
else if(i->op3 == 0x24)
m = "FMOVF";
}
bprint(i, "%s\t", m);
if(i->op3 == 0x25)
bprint(i, "FSR, ");
else if(i->op3 == 0x26)
bprint(i, "FQ, ");
else
bprint(i, "R%d, ", i->rd);
if(i->i == 0)
bprint(i, "(R%d+R%d)", i->rs1, i->rs2);
else
address(i);
}
static
void loadc(Instr *i, char *m) /* page 72 */
{
if(i->i == 0)
bprint(i, "%s\t(R%d+R%d), C%d", m, i->rs1, i->rs2, i->rd);
else{
bprint(i, "%s\t", m);
address(i);
bprint(i, ", C%d", i->rd);
}
}
static
void loadcsr(Instr *i, char *m) /* page 72 */
{
if(i->i == 0)
bprint(i, "%s\t(R%d+R%d), CSR", m, i->rs1, i->rs2);
else{
bprint(i, "%s\t", m);
address(i);
bprint(i, ", CSR");
}
}
static struct
{
int opf;
char *name;
} fptab1[] = { /* ignores rs1 */
0xC4, "FITOS", /* page 109 */
0xC8, "FITOD",
0xCC, "FITOX",
0xD1, "FSTOI", /* page 110 */
0xD2, "FDTOI",
0xD3, "FXTOI",
0xC9, "FSTOD", /* page 111 */
0xCD, "FSTOX",
0xC6, "FDTOS",
0xCE, "FDTOX",
0xC7, "FXTOS",
0xCB, "FXTOD",
0x01, "FMOVS", /* page 112 */
0x05, "FNEGS",
0x09, "FABSS",
0x29, "FSQRTS", /* page 113 */
0x2A, "FSQRTD",
0x2B, "FSQRTX",
0, 0,
};
static struct{
int opf;
char *name;
} fptab2[] = { /* uses rs1 */
0x41, "FADDS", /* page 114 */
0x42, "FADDD",
0x43, "FADDX",
0x45, "FSUBS",
0x46, "FSUBD",
0x47, "FSUBX",
0x49, "FMULS", /* page 115 */
0x4A, "FMULD",
0x4B, "FMULX",
0x4D, "FDIVS",
0x4E, "FDIVD",
0x4F, "FDIVX",
0x51, "FCMPS", /* page 116 */
0x52, "FCMPD",
0x53, "FCMPX",
0x55, "FCMPES",
0x56, "FCMPED",
0x57, "FCMPEX",
0, 0
};
static void
fpop(Instr *i, char *m) /* page 108-116 */
{
int j;
if(dascase==0 && i->size==2){
bprint(i, "FMOVD\tF%d, F%d", i->rs2, i->rd);
return;
}
for(j=0; fptab1[j].name; j++)
if(fptab1[j].opf == i->opf){
bprint(i, "%s\tF%d, F%d", fptab1[j].name, i->rs2, i->rd);
return;
}
for(j=0; fptab2[j].name; j++)
if(fptab2[j].opf == i->opf){
bprint(i, "%s\tF%d, F%d, F%d", fptab2[j].name, i->rs1, i->rs2, i->rd);
return;
}
bprint(i, "%s%ux\tF%d, F%d, F%d", m, i->opf, i->rs1, i->rs2, i->rd);
}