Forgot to check these changes in yesterday.
This commit is contained in:
parent
7d1257bb57
commit
f6061456e0
1 changed files with 186 additions and 1 deletions
187
bfd/libhppa.h
187
bfd/libhppa.h
|
@ -123,6 +123,22 @@ enum hppa_reloc_expr_type_alt
|
|||
};
|
||||
|
||||
|
||||
/* Relocations for function calls must be accompanied by parameter
|
||||
relocation bits. These bits describe exactly where the caller has
|
||||
placed the function's arguments and where it expects to find a return
|
||||
value.
|
||||
|
||||
Both ELF and SOM encode this information within the addend field
|
||||
of the call relocation. (Note this could break very badly if one
|
||||
was to make a call like bl foo + 0x12345678).
|
||||
|
||||
The high order 10 bits contain parameter relocation information,
|
||||
the low order 22 bits contain the constant offset. */
|
||||
|
||||
#define HPPA_R_ARG_RELOC(a) (((a) >> 22) & 0x3FF)
|
||||
#define HPPA_R_CONSTANT(a) ((((int)(a)) << 10) >> 10)
|
||||
#define HPPA_R_ADDEND(r,c) (((r) << 22) + ((c) & 0x3FFFFF))
|
||||
|
||||
/* Some functions to manipulate PA instructions. */
|
||||
static INLINE unsigned int
|
||||
assemble_3 (x)
|
||||
|
@ -291,7 +307,6 @@ hppa_field_adjust (value, constant_value, r_field)
|
|||
unsigned long constant_value;
|
||||
unsigned short r_field;
|
||||
{
|
||||
unsigned long init_value = value;
|
||||
value += constant_value;
|
||||
switch (r_field)
|
||||
{
|
||||
|
@ -346,4 +361,174 @@ hppa_field_adjust (value, constant_value, r_field)
|
|||
return value;
|
||||
|
||||
}
|
||||
|
||||
/* PA-RISC OPCODES */
|
||||
#define get_opcode(insn) ((insn) & 0xfc000000) >> 26
|
||||
|
||||
/* FIXME: this list is incomplete. It should also be an enumerated
|
||||
type rather than #defines. */
|
||||
|
||||
#define LDO 0x0d
|
||||
#define LDB 0x10
|
||||
#define LDH 0x11
|
||||
#define LDW 0x12
|
||||
#define LDWM 0x13
|
||||
#define STB 0x18
|
||||
#define STH 0x19
|
||||
#define STW 0x1a
|
||||
#define STWM 0x1b
|
||||
#define COMICLR 0x24
|
||||
#define SUBI 0x25
|
||||
#define SUBIO 0x25
|
||||
#define ADDIT 0x2c
|
||||
#define ADDITO 0x2c
|
||||
#define ADDI 0x2d
|
||||
#define ADDIO 0x2d
|
||||
#define LDIL 0x08
|
||||
#define ADDIL 0x0a
|
||||
|
||||
#define MOVB 0x32
|
||||
#define MOVIB 0x33
|
||||
#define COMBT 0x20
|
||||
#define COMBF 0x22
|
||||
#define COMIBT 0x21
|
||||
#define COMIBF 0x23
|
||||
#define ADDBT 0x28
|
||||
#define ADDBF 0x2a
|
||||
#define ADDIBT 0x29
|
||||
#define ADDIBF 0x2b
|
||||
#define BVB 0x30
|
||||
#define BB 0x31
|
||||
|
||||
#define BL 0x3a
|
||||
#define BLE 0x39
|
||||
#define BE 0x38
|
||||
|
||||
|
||||
/* Given a machine instruction, return its format.
|
||||
|
||||
FIXME: opcodes which do not map to a known format
|
||||
should return an error of some sort. */
|
||||
|
||||
static char
|
||||
bfd_hppa_insn2fmt (insn)
|
||||
unsigned long insn;
|
||||
{
|
||||
char fmt = -1;
|
||||
unsigned char op = get_opcode (insn);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case ADDI:
|
||||
case ADDIT:
|
||||
case SUBI:
|
||||
fmt = 11;
|
||||
break;
|
||||
case MOVB:
|
||||
case MOVIB:
|
||||
case COMBT:
|
||||
case COMBF:
|
||||
case COMIBT:
|
||||
case COMIBF:
|
||||
case ADDBT:
|
||||
case ADDBF:
|
||||
case ADDIBT:
|
||||
case ADDIBF:
|
||||
case BVB:
|
||||
case BB:
|
||||
fmt = 12;
|
||||
break;
|
||||
case LDO:
|
||||
case LDB:
|
||||
case LDH:
|
||||
case LDW:
|
||||
case LDWM:
|
||||
case STB:
|
||||
case STH:
|
||||
case STW:
|
||||
case STWM:
|
||||
fmt = 14;
|
||||
break;
|
||||
case BL:
|
||||
case BE:
|
||||
case BLE:
|
||||
fmt = 17;
|
||||
break;
|
||||
case LDIL:
|
||||
case ADDIL:
|
||||
fmt = 21;
|
||||
break;
|
||||
default:
|
||||
fmt = 32;
|
||||
break;
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
|
||||
/* Insert VALUE into INSN using R_FORMAT to determine exactly what
|
||||
bits to change. */
|
||||
|
||||
static unsigned long
|
||||
hppa_rebuild_insn (abfd, insn, value, r_format)
|
||||
bfd *abfd;
|
||||
unsigned long insn;
|
||||
unsigned long value;
|
||||
unsigned long r_format;
|
||||
{
|
||||
unsigned long const_part;
|
||||
unsigned long rebuilt_part;
|
||||
|
||||
switch (r_format)
|
||||
{
|
||||
case 11:
|
||||
{
|
||||
unsigned w1, w;
|
||||
|
||||
const_part = insn & 0xffffe002;
|
||||
dis_assemble_12 (value, &w1, &w);
|
||||
rebuilt_part = (w1 << 2) | w;
|
||||
return const_part | rebuilt_part;
|
||||
}
|
||||
|
||||
case 12:
|
||||
{
|
||||
unsigned w1, w;
|
||||
|
||||
const_part = insn & 0xffffe002;
|
||||
dis_assemble_12 (value, &w1, &w);
|
||||
rebuilt_part = (w1 << 2) | w;
|
||||
return const_part | rebuilt_part;
|
||||
}
|
||||
|
||||
case 14:
|
||||
const_part = insn & 0xffffc000;
|
||||
low_sign_unext (value, 14, &rebuilt_part);
|
||||
return const_part | rebuilt_part;
|
||||
|
||||
case 17:
|
||||
{
|
||||
unsigned w1, w2, w;
|
||||
|
||||
const_part = insn & 0xffe0e002;
|
||||
dis_assemble_17 (value, &w1, &w2, &w);
|
||||
rebuilt_part = (w2 << 2) | (w1 << 16) | w;
|
||||
return const_part | rebuilt_part;
|
||||
}
|
||||
|
||||
case 21:
|
||||
const_part = insn & 0xffe00000;
|
||||
dis_assemble_21 (value, &rebuilt_part);
|
||||
return const_part | rebuilt_part;
|
||||
|
||||
case 32:
|
||||
const_part = 0;
|
||||
return value;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
return insn;
|
||||
}
|
||||
|
||||
#endif /* _HPPA_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue