forked from Imagelibrary/binutils-gdb
* config/tc-ia64.c (FUNC_PC_RELATIVE): New.
(pseudo_func): Add pcrel.
(operand_match): Handle IA64_OPND_TGT64.
(build_insn): Likewise.
(md_begin): Initialize pseudo_func[FUNC_PC_RELATIVE].
(ia64_gen_real_reloc_type): Handle FUNC_PC_RELATIVE.
(fix_insn): Handle all three 64-bit relocation types.
This commit is contained in:
@@ -1,3 +1,13 @@
|
|||||||
|
2000-05-22 Richard Henderson <rth@cygnus.com>
|
||||||
|
|
||||||
|
* config/tc-ia64.c (FUNC_PC_RELATIVE): New.
|
||||||
|
(pseudo_func): Add pcrel.
|
||||||
|
(operand_match): Handle IA64_OPND_TGT64.
|
||||||
|
(build_insn): Likewise.
|
||||||
|
(md_begin): Initialize pseudo_func[FUNC_PC_RELATIVE].
|
||||||
|
(ia64_gen_real_reloc_type): Handle FUNC_PC_RELATIVE.
|
||||||
|
(fix_insn): Handle all three 64-bit relocation types.
|
||||||
|
|
||||||
Mon May 22 22:43:32 2000 Hans-Peter Nilsson <hp@axis.com>
|
Mon May 22 22:43:32 2000 Hans-Peter Nilsson <hp@axis.com>
|
||||||
|
|
||||||
* obj.h (struct format_ops): New members begin, app_file,
|
* obj.h (struct format_ops): New members begin, app_file,
|
||||||
@@ -410,7 +420,7 @@ Tue Apr 25 11:02:02 2000 Jeffrey A Law (law@cygnus.com)
|
|||||||
Fri Apr 21 14:29:43 2000 Jeffrey A Law (law@cygnus.com)
|
Fri Apr 21 14:29:43 2000 Jeffrey A Law (law@cygnus.com)
|
||||||
Jason Eckhardt <jle@cygnus.com>
|
Jason Eckhardt <jle@cygnus.com>
|
||||||
|
|
||||||
* config/tc-hppa.c (md_apply_fix): Handle new PA2.0 formats.
|
* config/tc-hppa.c (md_apply_fix): Handle new PA2.0 formats.
|
||||||
|
|
||||||
* config/tc-hppa.c (CHECK_ALIGN): New macro.
|
* config/tc-hppa.c (CHECK_ALIGN): New macro.
|
||||||
Added handling of new operand types l,y,&,fe,fE,fx.
|
Added handling of new operand types l,y,&,fe,fE,fx.
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ enum reloc_func
|
|||||||
FUNC_FPTR_RELATIVE,
|
FUNC_FPTR_RELATIVE,
|
||||||
FUNC_GP_RELATIVE,
|
FUNC_GP_RELATIVE,
|
||||||
FUNC_LT_RELATIVE,
|
FUNC_LT_RELATIVE,
|
||||||
|
FUNC_PC_RELATIVE,
|
||||||
FUNC_PLT_RELATIVE,
|
FUNC_PLT_RELATIVE,
|
||||||
FUNC_SEC_RELATIVE,
|
FUNC_SEC_RELATIVE,
|
||||||
FUNC_SEG_RELATIVE,
|
FUNC_SEG_RELATIVE,
|
||||||
@@ -434,6 +435,7 @@ pseudo_func[] =
|
|||||||
{ "fptr", PSEUDO_FUNC_RELOC },
|
{ "fptr", PSEUDO_FUNC_RELOC },
|
||||||
{ "gprel", PSEUDO_FUNC_RELOC },
|
{ "gprel", PSEUDO_FUNC_RELOC },
|
||||||
{ "ltoff", PSEUDO_FUNC_RELOC },
|
{ "ltoff", PSEUDO_FUNC_RELOC },
|
||||||
|
{ "pcrel", PSEUDO_FUNC_RELOC },
|
||||||
{ "pltoff", PSEUDO_FUNC_RELOC },
|
{ "pltoff", PSEUDO_FUNC_RELOC },
|
||||||
{ "secrel", PSEUDO_FUNC_RELOC },
|
{ "secrel", PSEUDO_FUNC_RELOC },
|
||||||
{ "segrel", PSEUDO_FUNC_RELOC },
|
{ "segrel", PSEUDO_FUNC_RELOC },
|
||||||
@@ -4003,9 +4005,11 @@ operand_match (idesc, index, e)
|
|||||||
fix->code = BFD_RELOC_IA64_PCREL21M;
|
fix->code = BFD_RELOC_IA64_PCREL21M;
|
||||||
else if (opnd == IA64_OPND_TGT25c)
|
else if (opnd == IA64_OPND_TGT25c)
|
||||||
fix->code = BFD_RELOC_IA64_PCREL21B;
|
fix->code = BFD_RELOC_IA64_PCREL21B;
|
||||||
else
|
else if (opnd == IA64_OPND_TGT64)
|
||||||
/* FIXME -- use appropriate relocation type */
|
fix->code = BFD_RELOC_IA64_PCREL60B;
|
||||||
as_bad (_("long branch targets not implemented"));
|
else
|
||||||
|
abort ();
|
||||||
|
|
||||||
fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
|
fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
|
||||||
fix->opnd = idesc->operands[index];
|
fix->opnd = idesc->operands[index];
|
||||||
fix->expr = *e;
|
fix->expr = *e;
|
||||||
@@ -4222,86 +4226,109 @@ build_insn (slot, insnp)
|
|||||||
|
|
||||||
for (i = 0; i < NELEMS (idesc->operands) && idesc->operands[i]; ++i)
|
for (i = 0; i < NELEMS (idesc->operands) && idesc->operands[i]; ++i)
|
||||||
{
|
{
|
||||||
if (idesc->operands[i] == IA64_OPND_IMMU64)
|
if (slot->opnd[i].X_op == O_register
|
||||||
|
|| slot->opnd[i].X_op == O_constant
|
||||||
|
|| slot->opnd[i].X_op == O_index)
|
||||||
|
val = slot->opnd[i].X_add_number;
|
||||||
|
else if (slot->opnd[i].X_op == O_big)
|
||||||
{
|
{
|
||||||
val = slot->opnd[i].X_add_number;
|
/* This must be the value 0x10000000000000000. */
|
||||||
|
assert (idesc->operands[i] == IA64_OPND_IMM8M1U8);
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
switch (idesc->operands[i])
|
||||||
|
{
|
||||||
|
case IA64_OPND_IMMU64:
|
||||||
*insnp++ = (val >> 22) & 0x1ffffffffffLL;
|
*insnp++ = (val >> 22) & 0x1ffffffffffLL;
|
||||||
insn |= (((val & 0x7f) << 13) | (((val >> 7) & 0x1ff) << 27)
|
insn |= (((val & 0x7f) << 13) | (((val >> 7) & 0x1ff) << 27)
|
||||||
| (((val >> 16) & 0x1f) << 22) | (((val >> 21) & 0x1) << 21)
|
| (((val >> 16) & 0x1f) << 22) | (((val >> 21) & 0x1) << 21)
|
||||||
| (((val >> 63) & 0x1) << 36));
|
| (((val >> 63) & 0x1) << 36));
|
||||||
}
|
continue;
|
||||||
else if (idesc->operands[i] == IA64_OPND_IMMU62)
|
|
||||||
{
|
case IA64_OPND_IMMU62:
|
||||||
val = slot->opnd[i].X_add_number & 0x3fffffffffffffffULL;
|
val &= 0x3fffffffffffffffULL;
|
||||||
if (val != slot->opnd[i].X_add_number)
|
if (val != slot->opnd[i].X_add_number)
|
||||||
as_warn (_("Value truncated to 62 bits"));
|
as_warn (_("Value truncated to 62 bits"));
|
||||||
*insnp++ = (val >> 21) & 0x1ffffffffffLL;
|
*insnp++ = (val >> 21) & 0x1ffffffffffLL;
|
||||||
insn |= (((val & 0xfffff) << 6) | (((val >> 20) & 0x1) << 36));
|
insn |= (((val & 0xfffff) << 6) | (((val >> 20) & 0x1) << 36));
|
||||||
}
|
continue;
|
||||||
else if (idesc->operands[i] == IA64_OPND_TGT64)
|
|
||||||
{
|
case IA64_OPND_TGT64:
|
||||||
// FIXME -- need to implement the target address encoding properly
|
val >>= 4;
|
||||||
as_bad (_("long branch target encoding not implemented"));
|
*insnp++ = ((val >> 20) & 0x7fffffffffLL) << 2;
|
||||||
*insnp++ = 0;
|
insn |= ((((val >> 59) & 0x1) << 36)
|
||||||
}
|
| (((val >> 0) & 0xfffff) << 13));
|
||||||
else if (slot->opnd[i].X_op == O_register
|
continue;
|
||||||
|| slot->opnd[i].X_op == O_constant
|
|
||||||
|| slot->opnd[i].X_op == O_index
|
case IA64_OPND_AR3:
|
||||||
|| slot->opnd[i].X_op == O_big)
|
val -= REG_AR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IA64_OPND_B1:
|
||||||
|
case IA64_OPND_B2:
|
||||||
|
val -= REG_BR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IA64_OPND_CR3:
|
||||||
|
val -= REG_CR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IA64_OPND_F1:
|
||||||
|
case IA64_OPND_F2:
|
||||||
|
case IA64_OPND_F3:
|
||||||
|
case IA64_OPND_F4:
|
||||||
|
val -= REG_FR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IA64_OPND_P1:
|
||||||
|
case IA64_OPND_P2:
|
||||||
|
val -= REG_P;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IA64_OPND_R1:
|
||||||
|
case IA64_OPND_R2:
|
||||||
|
case IA64_OPND_R3:
|
||||||
|
case IA64_OPND_R3_2:
|
||||||
|
case IA64_OPND_CPUID_R3:
|
||||||
|
case IA64_OPND_DBR_R3:
|
||||||
|
case IA64_OPND_DTR_R3:
|
||||||
|
case IA64_OPND_ITR_R3:
|
||||||
|
case IA64_OPND_IBR_R3:
|
||||||
|
case IA64_OPND_MR3:
|
||||||
|
case IA64_OPND_MSR_R3:
|
||||||
|
case IA64_OPND_PKR_R3:
|
||||||
|
case IA64_OPND_PMC_R3:
|
||||||
|
case IA64_OPND_PMD_R3:
|
||||||
|
case IA64_OPND_RR_R3:
|
||||||
|
val -= REG_GR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
odesc = elf64_ia64_operands + idesc->operands[i];
|
||||||
|
err = (*odesc->insert) (odesc, val, &insn);
|
||||||
|
if (err)
|
||||||
|
as_bad_where (slot->src_file, slot->src_line,
|
||||||
|
"Bad operand value: %s", err);
|
||||||
|
if (idesc->flags & IA64_OPCODE_PSEUDO)
|
||||||
{
|
{
|
||||||
if (slot->opnd[i].X_op == O_big)
|
if ((idesc->flags & IA64_OPCODE_F2_EQ_F3)
|
||||||
|
&& odesc == elf64_ia64_operands + IA64_OPND_F3)
|
||||||
{
|
{
|
||||||
/* This must be the value 0x10000000000000000. */
|
o2desc = elf64_ia64_operands + IA64_OPND_F2;
|
||||||
assert (idesc->operands[i] == IA64_OPND_IMM8M1U8);
|
(*o2desc->insert) (o2desc, val, &insn);
|
||||||
val = 0;
|
|
||||||
}
|
}
|
||||||
else
|
if ((idesc->flags & IA64_OPCODE_LEN_EQ_64MCNT)
|
||||||
val = slot->opnd[i].X_add_number;
|
&& (odesc == elf64_ia64_operands + IA64_OPND_CPOS6a
|
||||||
|
|| odesc == elf64_ia64_operands + IA64_OPND_POS6))
|
||||||
switch (idesc->operands[i])
|
|
||||||
{
|
{
|
||||||
case IA64_OPND_AR3: val -= REG_AR; break;
|
o2desc = elf64_ia64_operands + IA64_OPND_LEN6;
|
||||||
case IA64_OPND_B1: case IA64_OPND_B2: val -= REG_BR; break;
|
(*o2desc->insert) (o2desc, 64 - val, &insn);
|
||||||
case IA64_OPND_CR3: val -= REG_CR; break;
|
|
||||||
case IA64_OPND_F1: case IA64_OPND_F2:
|
|
||||||
case IA64_OPND_F3: case IA64_OPND_F4: val -= REG_FR; break;
|
|
||||||
case IA64_OPND_P1: case IA64_OPND_P2: val -= REG_P; break;
|
|
||||||
|
|
||||||
case IA64_OPND_R1: case IA64_OPND_R2:
|
|
||||||
case IA64_OPND_R3: case IA64_OPND_R3_2:
|
|
||||||
case IA64_OPND_CPUID_R3: case IA64_OPND_DBR_R3:
|
|
||||||
case IA64_OPND_DTR_R3: case IA64_OPND_ITR_R3:
|
|
||||||
case IA64_OPND_IBR_R3: case IA64_OPND_MR3:
|
|
||||||
case IA64_OPND_MSR_R3: case IA64_OPND_PKR_R3:
|
|
||||||
case IA64_OPND_PMC_R3: case IA64_OPND_PMD_R3:
|
|
||||||
case IA64_OPND_RR_R3:
|
|
||||||
val -= REG_GR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
odesc = elf64_ia64_operands + idesc->operands[i];
|
|
||||||
err = (*odesc->insert) (odesc, val, &insn);
|
|
||||||
if (err)
|
|
||||||
as_bad_where (slot->src_file, slot->src_line,
|
|
||||||
"Bad operand value: %s", err);
|
|
||||||
if (idesc->flags & IA64_OPCODE_PSEUDO)
|
|
||||||
{
|
|
||||||
if ((idesc->flags & IA64_OPCODE_F2_EQ_F3)
|
|
||||||
&& odesc == elf64_ia64_operands + IA64_OPND_F3)
|
|
||||||
{
|
|
||||||
o2desc = elf64_ia64_operands + IA64_OPND_F2;
|
|
||||||
(*o2desc->insert) (o2desc, val, &insn);
|
|
||||||
|
|
||||||
}
|
|
||||||
if ((idesc->flags & IA64_OPCODE_LEN_EQ_64MCNT)
|
|
||||||
&& (odesc == elf64_ia64_operands + IA64_OPND_CPOS6a
|
|
||||||
|| odesc == elf64_ia64_operands + IA64_OPND_POS6))
|
|
||||||
{
|
|
||||||
o2desc = elf64_ia64_operands + IA64_OPND_LEN6;
|
|
||||||
(*o2desc->insert) (o2desc, 64 - val, &insn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4797,6 +4824,10 @@ md_begin ()
|
|||||||
symbol_new (".<ltoff>", undefined_section, FUNC_LT_RELATIVE,
|
symbol_new (".<ltoff>", undefined_section, FUNC_LT_RELATIVE,
|
||||||
&zero_address_frag);
|
&zero_address_frag);
|
||||||
|
|
||||||
|
pseudo_func[FUNC_PC_RELATIVE].u.sym =
|
||||||
|
symbol_new (".<pcrel>", undefined_section, FUNC_PC_RELATIVE,
|
||||||
|
&zero_address_frag);
|
||||||
|
|
||||||
pseudo_func[FUNC_PLT_RELATIVE].u.sym =
|
pseudo_func[FUNC_PLT_RELATIVE].u.sym =
|
||||||
symbol_new (".<pltoff>", undefined_section, FUNC_PLT_RELATIVE,
|
symbol_new (".<pltoff>", undefined_section, FUNC_PLT_RELATIVE,
|
||||||
&zero_address_frag);
|
&zero_address_frag);
|
||||||
@@ -7960,6 +7991,19 @@ ia64_gen_real_reloc_type (sym, r_type)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FUNC_PC_RELATIVE:
|
||||||
|
switch (r_type)
|
||||||
|
{
|
||||||
|
case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_PCREL22; break;
|
||||||
|
case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_PCREL64I; break;
|
||||||
|
case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_PCREL32MSB; break;
|
||||||
|
case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_PCREL32LSB; break;
|
||||||
|
case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_PCREL64MSB; break;
|
||||||
|
case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_PCREL64LSB; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case FUNC_PLT_RELATIVE:
|
case FUNC_PLT_RELATIVE:
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
{
|
{
|
||||||
@@ -8063,7 +8107,7 @@ fix_insn (fix, odesc, value)
|
|||||||
slot = fix->fx_where & 0x3;
|
slot = fix->fx_where & 0x3;
|
||||||
fixpos = fix->fx_frag->fr_literal + (fix->fx_where - slot);
|
fixpos = fix->fx_frag->fr_literal + (fix->fx_where - slot);
|
||||||
|
|
||||||
/* bundles are always in little-endian byte order */
|
/* Bundles are always in little-endian byte order */
|
||||||
t0 = bfd_getl64 (fixpos);
|
t0 = bfd_getl64 (fixpos);
|
||||||
t1 = bfd_getl64 (fixpos + 8);
|
t1 = bfd_getl64 (fixpos + 8);
|
||||||
control_bits = t0 & 0x1f;
|
control_bits = t0 & 0x1f;
|
||||||
@@ -8071,18 +8115,40 @@ fix_insn (fix, odesc, value)
|
|||||||
insn[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18);
|
insn[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18);
|
||||||
insn[2] = (t1 >> 23) & 0x1ffffffffffLL;
|
insn[2] = (t1 >> 23) & 0x1ffffffffffLL;
|
||||||
|
|
||||||
err = (*odesc->insert) (odesc, value, insn + slot);
|
err = NULL;
|
||||||
if (err)
|
if (odesc - elf64_ia64_operands == IA64_OPND_IMMU64)
|
||||||
{
|
{
|
||||||
as_bad_where (fix->fx_file, fix->fx_line, err);
|
insn[1] = (value >> 22) & 0x1ffffffffffLL;
|
||||||
return;
|
insn[2] |= (((value & 0x7f) << 13)
|
||||||
|
| (((value >> 7) & 0x1ff) << 27)
|
||||||
|
| (((value >> 16) & 0x1f) << 22)
|
||||||
|
| (((value >> 21) & 0x1) << 21)
|
||||||
|
| (((value >> 63) & 0x1) << 36));
|
||||||
}
|
}
|
||||||
|
else if (odesc - elf64_ia64_operands == IA64_OPND_IMMU62)
|
||||||
|
{
|
||||||
|
if (value & ~0x3fffffffffffffffULL)
|
||||||
|
err = "integer operand out of range";
|
||||||
|
insn[1] = (value >> 21) & 0x1ffffffffffLL;
|
||||||
|
insn[2] |= (((value & 0xfffff) << 6) | (((value >> 20) & 0x1) << 36));
|
||||||
|
}
|
||||||
|
else if (odesc - elf64_ia64_operands == IA64_OPND_TGT64)
|
||||||
|
{
|
||||||
|
value >>= 4;
|
||||||
|
insn[1] = ((value >> 20) & 0x7fffffffffLL) << 2;
|
||||||
|
insn[2] |= ((((value >> 59) & 0x1) << 36)
|
||||||
|
| (((value >> 0) & 0xfffff) << 13));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = (*odesc->insert) (odesc, value, insn + slot);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
as_bad_where (fix->fx_file, fix->fx_line, err);
|
||||||
|
|
||||||
t0 = control_bits | (insn[0] << 5) | (insn[1] << 46);
|
t0 = control_bits | (insn[0] << 5) | (insn[1] << 46);
|
||||||
t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
|
t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
|
||||||
md_number_to_chars (fixpos + 0, t0, 8);
|
md_number_to_chars (fixpos + 0, t0, 8);
|
||||||
md_number_to_chars (fixpos + 8, t1, 8);
|
md_number_to_chars (fixpos + 8, t1, 8);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to simplify or even eliminate a fixup. The return value is
|
/* Attempt to simplify or even eliminate a fixup. The return value is
|
||||||
|
|||||||
Reference in New Issue
Block a user