Handle relativism, public ppc macros

This commit is contained in:
Sajid 2024-09-09 08:13:57 +06:00
parent 6d1e649eaf
commit 606463ac09
3 changed files with 52 additions and 23 deletions

View File

@ -418,6 +418,7 @@ typedef struct powerpc_opcode
typedef struct ppc_insn typedef struct ppc_insn
{ {
const powerpc_opcode* opcode; const powerpc_opcode* opcode;
uint32_t instruction;
uint32_t operands[8]; uint32_t operands[8];
char op_str[160]; char op_str[160];
} ppc_insn; } ppc_insn;

View File

@ -145,9 +145,6 @@ extern const int powerpc_num_opcodes;
/* Opcode is only supported by PowerPC Cell family. */ /* Opcode is only supported by PowerPC Cell family. */
#define PPC_OPCODE_CELL 0x8000000 #define PPC_OPCODE_CELL 0x8000000
/* A macro to extract the major opcode from an instruction. */
#define PPC_OP(i) (((i) >> 26) & 0x3f)
/* The operands table is an array of struct powerpc_operand. */ /* The operands table is an array of struct powerpc_operand. */
struct powerpc_operand struct powerpc_operand
@ -1611,9 +1608,9 @@ extract_tbr(unsigned long insn,
static unsigned long static unsigned long
insert_vds128 (unsigned long insn, insert_vds128 (unsigned long insn,
long value, long value,
int dialect ATTRIBUTE_UNUSED, int dialect ATTRIBUTE_UNUSED,
const char **errmsg ATTRIBUTE_UNUSED) const char **errmsg ATTRIBUTE_UNUSED)
{ {
return insn | ((value & 0x60) >> 3) | ((value & 0x1f) << 21); return insn | ((value & 0x60) >> 3) | ((value & 0x1f) << 21);
@ -1621,8 +1618,8 @@ insert_vds128 (unsigned long insn,
static long static long
extract_vds128 (unsigned long insn, extract_vds128 (unsigned long insn,
int dialect ATTRIBUTE_UNUSED, int dialect ATTRIBUTE_UNUSED,
int *invalid ATTRIBUTE_UNUSED) int *invalid ATTRIBUTE_UNUSED)
{ {
return ((insn << 3) & 0x60) | ((insn >> 21) & 0x1f); return ((insn << 3) & 0x60) | ((insn >> 21) & 0x1f);
} }
@ -1631,9 +1628,9 @@ extract_vds128 (unsigned long insn,
static unsigned long static unsigned long
insert_va128 (unsigned long insn, insert_va128 (unsigned long insn,
long value, long value,
int dialect ATTRIBUTE_UNUSED, int dialect ATTRIBUTE_UNUSED,
const char **errmsg ATTRIBUTE_UNUSED) const char **errmsg ATTRIBUTE_UNUSED)
{ {
return insn | ((value & 0x40) << 4) | (value & 0x20) return insn | ((value & 0x40) << 4) | (value & 0x20)
| ((value & 0x1f) << 16); | ((value & 0x1f) << 16);
@ -1641,8 +1638,8 @@ insert_va128 (unsigned long insn,
static long static long
extract_va128 (unsigned long insn, extract_va128 (unsigned long insn,
int dialect ATTRIBUTE_UNUSED, int dialect ATTRIBUTE_UNUSED,
int *invalid ATTRIBUTE_UNUSED) int *invalid ATTRIBUTE_UNUSED)
{ {
return ((insn >> 4) & 0x40) | (insn & 0x20) | ((insn >> 16) & 0x1f); return ((insn >> 4) & 0x40) | (insn & 0x20) | ((insn >> 16) & 0x1f);
} }
@ -1651,17 +1648,17 @@ extract_va128 (unsigned long insn,
static unsigned long static unsigned long
insert_vb128 (unsigned long insn, insert_vb128 (unsigned long insn,
long value, long value,
int dialect ATTRIBUTE_UNUSED, int dialect ATTRIBUTE_UNUSED,
const char **errmsg ATTRIBUTE_UNUSED) const char **errmsg ATTRIBUTE_UNUSED)
{ {
return insn | ((value & 0x60) >> 5) | ((value & 0x1f) << 11); return insn | ((value & 0x60) >> 5) | ((value & 0x1f) << 11);
} }
static long static long
extract_vb128 (unsigned long insn, extract_vb128 (unsigned long insn,
int dialect ATTRIBUTE_UNUSED, int dialect ATTRIBUTE_UNUSED,
int *invalid ATTRIBUTE_UNUSED) int *invalid ATTRIBUTE_UNUSED)
{ {
return ((insn << 5) & 0x60) | ((insn >> 11) & 0x1f); return ((insn << 5) & 0x60) | ((insn >> 11) & 0x1f);
} }
@ -1670,17 +1667,17 @@ extract_vb128 (unsigned long insn,
static unsigned long static unsigned long
insert_vperm (unsigned long insn, insert_vperm (unsigned long insn,
long value, long value,
int dialect ATTRIBUTE_UNUSED, int dialect ATTRIBUTE_UNUSED,
const char **errmsg ATTRIBUTE_UNUSED) const char **errmsg ATTRIBUTE_UNUSED)
{ {
return insn | ((value & 0xe0) << 1) | ((value & 0x1f) << 16); return insn | ((value & 0xe0) << 1) | ((value & 0x1f) << 16);
} }
static long static long
extract_vperm (unsigned long insn, extract_vperm (unsigned long insn,
int dialect ATTRIBUTE_UNUSED, int dialect ATTRIBUTE_UNUSED,
int *invalid ATTRIBUTE_UNUSED) int *invalid ATTRIBUTE_UNUSED)
{ {
return ((insn >> 1) & 0xe0) | ((insn >> 16) & 0x1f); return ((insn >> 1) & 0xe0) | ((insn >> 16) & 0x1f);
} }
@ -5665,6 +5662,7 @@ static int decode_insn_powerpc(bfd_vma memaddr, disassemble_info* info, int bige
else else
insn = bfd_getl32(buffer); insn = bfd_getl32(buffer);
oinsn->instruction = insn;
/* Get the major opcode of the instruction. */ /* Get the major opcode of the instruction. */
op = PPC_OP(insn); op = PPC_OP(insn);
@ -5740,6 +5738,15 @@ again:
value = operand_value_powerpc(operand, insn, dialect); value = operand_value_powerpc(operand, insn, dialect);
oinsn->operands[i_op] = value; oinsn->operands[i_op] = value;
if (operand->flags & PPC_OPERAND_RELATIVE)
{
oinsn->operands[i_op] += memaddr;
}
else if (operand->flags & PPC_OPERAND_ABSOLUTE)
{
oinsn->operands[i_op] &= 0xffffffff;
}
if (need_comma) if (need_comma)
{ {
stream = stream + sprintf(stream, ","); stream = stream + sprintf(stream, ",");

View File

@ -1,5 +1,26 @@
#pragma once #pragma once
/* A macro to extract the major opcode from an instruction. */
#define PPC_OP(i) (((i) >> 26) & 0x3f)
/* A macro to extract the extended opcode from an instruction. */
#define PPC_XOP(i) (((i) >> 1) & 0x3ff)
#define PPC_OP_TDI 2
#define PPC_OP_TWI 3
#define PPC_OP_MULLI 7
#define PPC_OP_SUBFIC 8
#define PPC_OP_CMPLI 0xA
#define PPC_OP_CMPI 0xB
#define PPC_OP_ADDIC 0xC // addic
#define PPC_OP_ADDICR 0xD // addic.
#define PPC_OP_ADDI 0xE
#define PPC_OP_ADDIS 0xF
#define PPC_OP_BC 0x10
#define PPC_OP_SC 0x11
#define PPC_OP_B 0x12
#define PPC_OP_CTR 0x13
#define PPC_INST_ATTN 0 #define PPC_INST_ATTN 0
#define PPC_INST_TDLGTI 1 #define PPC_INST_TDLGTI 1
#define PPC_INST_TDLLTI 2 #define PPC_INST_TDLLTI 2