Forgot to check these changes in yesterday.

This commit is contained in:
Jeff Law 1994-02-27 19:18:06 +00:00
parent 7d1257bb57
commit f6061456e0
1 changed files with 186 additions and 1 deletions

View File

@ -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 */