📄 sparc_disas.cpp
字号:
#include <StdAfx.h>
#include "sparc_disas.h"
#include "sparc.h"
#include "string.h"
#include "stdio.h"
// return info
char dis_info[80];
// clear buffer function
void clear_buf()
{
for (int i = 0; i< 80; i++)
dis_info[i] = 0;
}
// change Hex to char function
char hextochar(char c)
{
int i;
char hexarray[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
char chararray[16] = {'0', '1', '2', '3','4', '5','6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f'};
for (i = 0; i < 16; i++)
{
if (hexarray[i] == c)
return chararray[i];
}
printf("hex is not exist \n");
return (char)0xff;
}
void tostf(long addr)
{
char str[10];
str[0] = hextochar(((addr >> 24) & 0xf0) >> 4);
str[1] = hextochar((addr >> 24) & 0x0f);
str[2] = hextochar(((addr >> 16) & 0xf0) >> 4);
str[3] = hextochar((addr >> 16) & 0x0f);
str[4] = hextochar(((addr >> 8) & 0xf0) >> 4);
str[5] = hextochar((addr >> 8) & 0x0f);
str[6] = hextochar(((addr >> 0) & 0xf0) >> 4);
str[7] = hextochar((addr >> 0) & 0x0f);
str[8] = ':';
str[9] = NULL;
strcat(dis_info, str);
}
void tostd(int vector)
{
char darr[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
char s[3];
s[0] = darr[vector / 10];
s[1] = darr[vector % 10];
s[2] = NULL;
strcat(dis_info, s);
}
void tost(long addr)
{
char str[10];
str[0] = hextochar(((addr >> 24) & 0xf0) >> 4);
str[1] = hextochar((addr >> 24) & 0x0f);
str[2] = hextochar(((addr >> 16) & 0xf0) >> 4);
str[3] = hextochar((addr >> 16) & 0x0f);
str[4] = hextochar(((addr >> 8) & 0xf0) >> 4);
str[5] = hextochar((addr >> 8) & 0x0f);
str[6] = hextochar(((addr >> 0) & 0xf0) >> 4);
str[7] = hextochar((addr >> 0) & 0x0f);
str[8] = NULL;
for (int i = 0; i < 8; i++)
{
if (str[i] != '0')
break;
}
for (int j = 0; j < 9 - i; j++)
str[j] = str[j + i];
strcat(dis_info, str);
}
void regres(PC_OP_TYPE insn, BASE_TYPE base)
{
int rs1 = 0;
int rs2 = 0;
int rd = 0;
int i = 0;
rd = (insn.op >> 25) & 0x1f;
regimm(insn, base, false);
if ((insn.op & 0xf0ffffff) == 0x90402000)
strcat(dis_info, ",");
else
strcat(dis_info, ", ");
ireg2st(rd);
}
void branchop(PC_OP_TYPE insn)
{
int simm = 0;
switch ((insn.op >> 25) & 0xf)
{
case 0:
strcat(dis_info, "n");
break;
case 1:
strcat(dis_info, "e");
break;
case 2:
strcat(dis_info, "le");
break;
case 3:
strcat(dis_info, "l");
break;
case 4:
strcat(dis_info, "leu");
break;
case 5:
strcat(dis_info, "cs");
break;
case 6:
strcat(dis_info, "neg");
break;
case 7:
strcat(dis_info, "vs");
break;
case 8:
strcat(dis_info, "a");
break;
case 9:
strcat(dis_info, "ne");
break;
case 10:
strcat(dis_info, "g");
break;
case 11:
strcat(dis_info, "ge");
break;
case 12:
strcat(dis_info, "gu");
break;
case 13:
strcat(dis_info, "cc");
break;
case 14:
strcat(dis_info, "pos");
break;
case 15:
strcat(dis_info, "vc");
break;
default:
strcat(dis_info, "XXX");
break;
}
}
void fbranchop(PC_OP_TYPE insn)
{
int simm = 0;
switch ((insn.op >> 25) & 0xf)
{
case 0:
strcat(dis_info, "n");
break;
case 1:
strcat(dis_info, "ne");
break;
case 2:
strcat(dis_info, "lg");
break;
case 3:
strcat(dis_info, "ul");
break;
case 4:
strcat(dis_info, "l");
break;
case 5:
strcat(dis_info, "ug");
break;
case 6:
strcat(dis_info, "g");
break;
case 7:
strcat(dis_info, "u");
break;
case 8:
strcat(dis_info, "a");
break;
case 9:
strcat(dis_info, "e");
break;
case 10:
strcat(dis_info, "ue");
break;
case 11:
strcat(dis_info, "ge");
break;
case 12:
strcat(dis_info, "uge");
break;
case 13:
strcat(dis_info, "le");
break;
case 14:
strcat(dis_info, "ule");
break;
case 15:
strcat(dis_info, "o");
break;
default:
strcat(dis_info, "XXX");
break;
}
}
void ireg2st(int v)
{
char c;
char str[10];
int reg = 0;
reg = v;
switch ((reg >> 3) & 0x3) // reg(4 downto 3)
{
case 0:
c = 'g';
break;
case 1:
c = 'o';
break;
case 2:
c = 'l';
break;
case 3:
c = 'i';
break;
default:
c = 'X';
break;
}
if ((v & 0x1f) == 0x1e)
{
strcat(dis_info, "%fp");
}
else if ((v & 0x1f) == 0x0e)
{
strcat(dis_info, "%sp");
}
else
{
str[0] = '%';
str[1] = c;
str[2] = hextochar(reg & 0x7);
str[3] = NULL;
strcat(dis_info, str);
}
return;
}
void freg2(PC_OP_TYPE insn)
{
int rs1 = 0;
int rs2 = 0;
int rd = 0;
int i = 0;
rs2 = insn.op & 0x1f;
rd = (insn.op >> 25) & 0x1f;
strcat(dis_info, "%f");
tostd(rs2);
strcat(dis_info, ", %f");
tostd(rd);
}
void creg3(PC_OP_TYPE insn)
{
int rs1 = 0;
int rs2 = 0;
int rd = 0;
int i = 0;
rs1 = (insn.op >> 14) & 0x1f;
rs2 = (insn.op >> 00) & 0x1f;
rd = (insn.op >> 25) & 0x1f;
strcat(dis_info, "%c");
tostd(rs1);
strcat(dis_info, ", %c");
tostd(rs2);
strcat(dis_info, ", %c");
tostd(rd);
}
void freg3(PC_OP_TYPE insn)
{
int rs1 = 0;
int rs2 = 0;
int rd = 0;
int i = 0;
rs1 = (insn.op >> 14) & 0x1f;
rs2 = (insn.op >> 00) & 0x1f;
rd = (insn.op >> 25) & 0x1f;
strcat(dis_info, "%f");
tostd(rs1);
strcat(dis_info, ", %f");
tostd(rs2);
strcat(dis_info, ", %f");
tostd(rd);
}
void fregc(PC_OP_TYPE insn)
{
int rs1 = 0;
int rs2 = 0;
int i = 0;
rs1 = (insn.op >> 14) & 0x1f;
rs2 = (insn.op >> 00) & 0x1f;
strcat(dis_info, "%f");
tostd(rs1);
strcat(dis_info, ", %f");
tostd(rs2);
}
void stparc(PC_OP_TYPE insn, int rd, BASE_TYPE base)
{
if (rd == 0)
{
strcat(dis_info, "[");
regimm(insn, DEC, true);
strcat(dis_info, "]");
}
else
{
ireg2st(rd);
strcat(dis_info, ", [");
regimm(insn, DEC, true);
strcat(dis_info, "]");
}
}
void stparcp(PC_OP_TYPE insn, int rd, BASE_TYPE base)
{
strcat(dis_info, "%c");
tost(rd);
strcat(dis_info, ", [");
regimm(insn, DEC, true);
strcat(dis_info, "]");
}
void stparf(PC_OP_TYPE insn, int rd, BASE_TYPE base)
{
strcat(dis_info, "%f");
tostd(rd);
strcat(dis_info, ", [");
regimm(insn, DEC, true);
strcat(dis_info, "]");
}
void stpar(PC_OP_TYPE insn, int rd, BASE_TYPE base)
{
ireg2st(rd);
strcat(dis_info, ", [");
regimm(insn, DEC, true);
strcat(dis_info, "]");
}
void stpara(PC_OP_TYPE insn, int rd, BASE_TYPE base)
{
ireg2st(rd);
strcat(dis_info, ", [");
regimm(insn, DEC, true);
strcat(dis_info, " ");
tost((insn.op >> 5) & 0xff);
}
void ldparcp(PC_OP_TYPE insn, int rd, BASE_TYPE base)
{
strcat(dis_info, "[");
regimm(insn, DEC, true);
strcat(dis_info, "]");
strcat(dis_info, ", ");
strcat(dis_info, "%c");
tost(rd);
}
void ldparf(PC_OP_TYPE insn, int rd, BASE_TYPE base)
{
strcat(dis_info, "[");
regimm(insn, DEC, true);
strcat(dis_info, "]");
strcat(dis_info, ", ");
strcat(dis_info, "%f");
tostd(rd);
}
void ldpar(PC_OP_TYPE insn, int rd, BASE_TYPE base)
{
strcat(dis_info, "[");
regimm(insn, DEC, true);
strcat(dis_info, "]");
strcat(dis_info, ", ");
ireg2st(rd);
}
void ldpara(PC_OP_TYPE insn, int rd, BASE_TYPE base)
{
strcat(dis_info, "[");
regimm(insn, DEC, true);
strcat(dis_info, "]");
strcat(dis_info, " ");
tost((insn.op >> 5) & 0xff);
strcat(dis_info, ", ");
ireg2st(rd);
}
void simm13dec(PC_OP_TYPE insn, BASE_TYPE base, bool merge)
{
int simm = 0;
int rs1 = 0;
int i = 0;
char sig;
char s[10];
int fill = 0;
simm = (insn.op >> 0) & 0x1fff;
rs1 = (insn.op >> 14) & 0x1f;
i = (insn.op >> 13) & 0x1;
if ((simm >> 12) & 0x1)
fill = 0xffffc000;
else
fill = 0x00000000;
if (i == 0)
strcat(dis_info, "");
else
{
if ((((simm >> 12) & 0x1) == 1) && (base == DEC))
{
sig = '-';
simm = ((~simm) + 1) & 0x1fff ;
}
else
{
sig = '+';
}
if (base == DEC)
{
if (merge)
{
if (rs1 == 0)
{
strcat(dis_info, "0x");
tost(simm);
}
else
{
s[0] = sig;
s[1] = NULL;
strcat(dis_info, s);
strcat(dis_info, "0x");
tost(simm);
}
}
else
{
if (rs1 == 0)
{
if ((insn.op & 0xf0ffffff) == 0x90402000)
{
strcat(dis_info, " ,0 ");
return;
}
strcat(dis_info, "0x");
tost(simm);
}
else
{
if (sig == '-')
{
strcat(dis_info, ", ");
s[0] = sig;
s[1] = NULL;
strcat(dis_info, s);
strcat(dis_info, "0x");
tost(simm);
}
else
{
strcat(dis_info, ", ");
strcat(dis_info, "0x");
tost(simm);
}
}
}
}
else
{
if (rs1 == 0)
{
if (((simm >> 12) & 0x1) == 1)
{
tost(fill | simm);
}
else
{
if (insn.op != 0x81d82000)
{
strcat(dis_info, "0x");
tost(simm);
}
}
}
else
{
if (((simm >> 12) & 0x1) == 1)
{
strcat(dis_info, ", ");
tost(fill | simm);
}
else
{
strcat(dis_info, ", ");
strcat(dis_info, "0x");
tost(simm);
}
}
}
}
}
void regimm(PC_OP_TYPE insn, BASE_TYPE base, bool merge)
{
int rs1 = 0;
int rs2 = 0;
int i = 0;
rs1 = (insn.op >> 14) & 0x1f;
rs2 = (insn.op >> 00) & 0x1f;
i = (insn.op >> 13) & 0x1;
if (i == 0)
{
if (rs1 == 0)
{
if (rs2 != 0) // fixed bug
strcat(dis_info, "0");
else
ireg2st(rs2);
}
else
{
if (rs2 == 0)
ireg2st(rs1);
else if (merge)
{
ireg2st(rs1);
strcat(dis_info, "+");
ireg2st(rs2);
}
else
{
ireg2st(rs1);
strcat(dis_info, ", ");
ireg2st(rs2);
}
}
}
else
{
if (((insn.op >> 0) & 0x1fff) == 0)
{
// patch "ta 0" code
if (insn.op == 0x91d02000)
strcat(dis_info, "0");
else
{
ireg2st(rs1);
simm13dec(insn, base, merge);
}
}
else if (rs1 == 0)
{
// fix the two op
// test_vector[0].op = 0x91e82001;
// test_vector[0].op = 0x90102001;
if ((insn.op >> 20) & 0x1)
{
// ireg2st(rs1); // fix bug
// strcat(dis_info, ", ");// fix bug
simm13dec(insn, base, merge);
}
else
{
ireg2st(rs1); // fix bug
strcat(dis_info, ", ");// fix bug
simm13dec(insn, base, merge);
}
}
else
{
ireg2st(rs1);
simm13dec(insn, base, merge);
}
}
}
char *ins2st(long pc, long op)
{
const int STMAX = 9;
char bl2[3];
char bb[5];
int op1 = 0;
int op2 = 0;
int op3 = 0;
int opf = 0;
int cond = 0;
int rs1 = 0;
int rs2 = 0;
int rd = 0;
long addr = 0;
int annul = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -