Rizin
unix-like reverse engineering framework and cli tools
libps.c File Reference
#include "libps.h"
#include "libps_internal.h"

Go to the source code of this file.

Functions

bool libps_decode (ut32 data, ppcps_t *ps)
 
void libps_snprint (char *str, int size, ut64 addr, ppcps_t *instr)
 

Variables

ps_operand_t ps_operands_array []
 
ps_opcode_t ps_opcodes_array []
 

Function Documentation

◆ libps_decode()

bool libps_decode ( ut32  data,
ppcps_t ps 
)

Definition at line 97 of file libps.c.

97  {
98  ut32 op = (data & OP_MASK);
99 
100  if ((op == OP(4)) || (op == OP(56)) ||
101  (op == OP(57)) || (op == OP(60)) ||
102  (op == OP(61))) {
103  ut32 size = sizeof(ps_opcodes_array) / sizeof(ps_opcode_t);
105 
106  ut32 l, j;
107  for (l = 0; l < size; l++) {
108  if ((data & instruction->mask) == instruction->opcode) {
109  j = 0;
110  for (; j < 6 && instruction->operands[j] != 0; j++) {
111  ppcps_field_t *field = &ps->operands[j];
112  ps_operand_t *ps_operand = &ps_operands_array[instruction->operands[j]];
113 
114  int bits = (data >> ps_operand->shift) & ((1 << ps_operand->bits) - 1);
115  // int ext_bits = (bits << (32 - ps_operand->bits)) >> (32 - ps_operand->bits);
116 
117  switch (instruction->operands[j]) {
118  case OP_FA:
119  case OP_FB:
120  case OP_FC:
121  case OP_FD: {
122  field->type = TYPE_REG;
123  field->value = bits;
124  break;
125  }
126 
127  case OP_RA:
128  case OP_RB: {
129  field->type = TYPE_REG;
130  field->value = bits;
131  break;
132  }
133 
134  case OP_crfD: {
135  field->type = TYPE_CR;
136  field->value = bits;
137  break;
138  }
139  case OP_WB:
140  case OP_IB:
141  case OP_WC:
142  case OP_IC: {
143  field->type = TYPE_IMM;
144  field->value = bits;
145  break;
146  }
147 
148  case OP_DRA: {
149  ut16 imm = (ut16)(data & 0x7FF);
150  ut16 sign = (ut16)(data & 0x800);
151  st16 displacement = 0;
152  if (sign == 0) {
153  displacement = imm;
154  } else {
155  displacement = -1 * imm;
156  }
157  field->type = TYPE_MEM;
158  field->value = bits + displacement;
159  break;
160  }
161 
162  default:
163  break;
164  }
165  }
166  ps->n = j;
167  ps->name = instruction->name;
168  ps->op = instruction->insn;
169  return true;
170  }
171  instruction++;
172  }
173  }
174  return false;
175 }
#define imm
@ TYPE_IMM
Definition: armass.c:35
@ TYPE_MEM
Definition: armass.c:36
int bits(struct state *s, int need)
Definition: blast.c:72
uint16_t ut16
uint32_t ut32
#define OP(v, w, x, y, z)
voidpf void uLong size
Definition: ioapi.h:138
ps_opcode_t ps_opcodes_array[]
Definition: libps.c:23
ps_operand_t ps_operands_array[]
Definition: libps.c:6
@ OP_FC
@ OP_RB
@ OP_WB
@ OP_RA
@ OP_IB
@ OP_FD
@ OP_FB
@ OP_FA
@ OP_DRA
@ OP_WC
@ OP_IC
@ OP_crfD
#define TYPE_CR
#define TYPE_REG
Definition: mcore.h:22
#define OP_MASK
Definition: nios2.h:467
#define st16
Definition: rz_types_base.h:14
ut32 value
Definition: libps.h:9
ut16 type
Definition: libps.h:10
ppcps_field_t operands[6]
Definition: libps.h:15
const char * name
Definition: libps.h:14
int op
Definition: libps.h:17
int n
Definition: libps.h:16
Definition: dis.c:32

References ps_operand_t::bits, bits(), imm, ppcps_t::n, ppcps_t::name, OP, ppcps_t::op, OP_crfD, OP_DRA, OP_FA, OP_FB, OP_FC, OP_FD, OP_IB, OP_IC, OP_MASK, OP_RA, OP_RB, OP_WB, OP_WC, ppcps_t::operands, ps_opcodes_array, ps_operands_array, ps_operand_t::shift, st16, ppcps_field_t::type, TYPE_CR, TYPE_IMM, TYPE_MEM, TYPE_REG, and ppcps_field_t::value.

Referenced by decompile_ps().

◆ libps_snprint()

void libps_snprint ( char *  str,
int  size,
ut64  addr,
ppcps_t instr 
)

Definition at line 177 of file libps.c.

177  {
178  ut32 i;
179  int bufsize = size, add = 0;
180  add = snprintf(str, bufsize, "%s", instr->name);
181  for (i = 0; add > 0 && i < instr->n && add < bufsize; i++) {
182  if (instr->operands[i].type == TYPE_REG) {
183  add += snprintf(str + add, bufsize - add, " fr%u", instr->operands[i].value);
184  } else if (instr->operands[i].type == TYPE_IMM) {
185  add += snprintf(str + add, bufsize - add, " 0x%x", instr->operands[i].value);
186  } else if (instr->operands[i].type == TYPE_MEM) {
187  add += snprintf(str + add, bufsize - add, " 0x%x(r%d)", instr->operands[i].value, instr->operands[i + 1].value);
188  i++;
189  } else if (instr->operands[i].type == TYPE_CR) {
190  add += snprintf(str + add, bufsize - add, " cr%u", instr->operands[i].value);
191  }
192  }
193 }
lzma_index ** i
Definition: index.h:629
snprintf
Definition: kernel.h:364
static int add(char *argv[])
Definition: ziptool.c:84

References add(), i, ppcps_t::n, ppcps_t::name, ppcps_t::operands, snprintf, cmd_descs_generate::str, ppcps_field_t::type, TYPE_CR, TYPE_IMM, TYPE_MEM, TYPE_REG, and ppcps_field_t::value.

Referenced by decompile_ps().

Variable Documentation

◆ ps_opcodes_array

ps_opcode_t ps_opcodes_array[]

Definition at line 23 of file libps.c.

Referenced by libps_decode().

◆ ps_operands_array

ps_operand_t ps_operands_array[]
Initial value:
= {
{ 0, 0 },
{ 5, 16 },
{ 5, 11 },
{ 5, 6 },
{ 5, 21 },
{ 3, 23 },
{ 1, 16 },
{ 3, 12 },
{ 1, 10 },
{ 3, 7 },
{ 5, 16 },
{ 5, 11 },
{ 5, 16 },
{ 5, 11 },
}

Definition at line 6 of file libps.c.

Referenced by libps_decode().