parent
849a0ebfb7
commit
49a5575c32
|
@ -1,3 +1,26 @@
|
||||||
|
1999-07-05 Nick Clifton <nickc@cygnus.com>
|
||||||
|
|
||||||
|
* config/tc-arm.c (ARM_EXT_V5): Define.
|
||||||
|
(ARM_ARCH_V5, ARM_ARCH_V5T): Define.
|
||||||
|
(md_begin): Detect ARM v5 architectures.
|
||||||
|
(md_parse_option): Accept arm v5 specification.
|
||||||
|
(md_show_usage): Documment -marmv5 switch.
|
||||||
|
|
||||||
|
* doc/c-arm.texi: Document -marmv5 command line option.
|
||||||
|
|
||||||
|
* config/tc-arm.c (do_adrl): New function. Implement ADRL pseudo
|
||||||
|
op.
|
||||||
|
(validate_immediate_twopart): New function. Determine if a
|
||||||
|
constant can be computed by two ADD instructions.
|
||||||
|
(output_inst): Remove its command line parameter - it was never
|
||||||
|
used.
|
||||||
|
(md_apply_fix3): Support BFD_RELOC_ARM_ADRL_IMMEDIATE, used to
|
||||||
|
implememt the ADRL pseudo op.
|
||||||
|
(tc_gen_reloc): Generate a suitable error message if an ADRL
|
||||||
|
instruction tries to generate a real reloc.
|
||||||
|
|
||||||
|
* doc/c-arm.texi: Document NOP, ADR and ADRL pseudo ops.
|
||||||
|
|
||||||
Thu Jul 1 15:33:10 1999 Jeffrey A Law (law@cygnus.com)
|
Thu Jul 1 15:33:10 1999 Jeffrey A Law (law@cygnus.com)
|
||||||
|
|
||||||
* config/tc-hppa.c (pa_ip): Convert the opcode and all completers
|
* config/tc-hppa.c (pa_ip): Convert the opcode and all completers
|
||||||
|
|
|
@ -51,12 +51,17 @@
|
||||||
#define ARM_LONGMUL 0x00000010 /* allow long multiplies */
|
#define ARM_LONGMUL 0x00000010 /* allow long multiplies */
|
||||||
#define ARM_HALFWORD 0x00000020 /* allow half word loads */
|
#define ARM_HALFWORD 0x00000020 /* allow half word loads */
|
||||||
#define ARM_THUMB 0x00000040 /* allow BX instruction */
|
#define ARM_THUMB 0x00000040 /* allow BX instruction */
|
||||||
|
#define ARM_EXT_V5 0x00000080 /* allow CLZ etc */
|
||||||
|
|
||||||
#define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
|
/* Architectures are the sum of the base and extensions */
|
||||||
|
#define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
|
||||||
|
#define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
|
||||||
|
#define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
|
||||||
|
#define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
|
||||||
|
|
||||||
/* Some useful combinations: */
|
/* Some useful combinations: */
|
||||||
#define ARM_ANY 0x00ffffff
|
#define ARM_ANY 0x00ffffff
|
||||||
#define ARM_2UP 0x00fffffe
|
#define ARM_2UP (ARM_ANY - ARM_1)
|
||||||
#define ARM_ALL ARM_2UP /* Not arm1 only */
|
#define ARM_ALL ARM_2UP /* Not arm1 only */
|
||||||
#define ARM_3UP 0x00fffffc
|
#define ARM_3UP 0x00fffffc
|
||||||
#define ARM_6UP 0x00fffff8 /* Includes ARM7 */
|
#define ARM_6UP 0x00fffff8 /* Includes ARM7 */
|
||||||
|
@ -73,7 +78,7 @@
|
||||||
|
|
||||||
#ifndef CPU_DEFAULT
|
#ifndef CPU_DEFAULT
|
||||||
#if defined __thumb__
|
#if defined __thumb__
|
||||||
#define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
|
#define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
|
||||||
#else
|
#else
|
||||||
#define CPU_DEFAULT ARM_ALL
|
#define CPU_DEFAULT ARM_ALL
|
||||||
#endif
|
#endif
|
||||||
|
@ -419,6 +424,7 @@ static void do_branch PARAMS ((char *operands, unsigned long flags));
|
||||||
static void do_swi PARAMS ((char *operands, unsigned long flags));
|
static void do_swi PARAMS ((char *operands, unsigned long flags));
|
||||||
/* Pseudo Op codes */
|
/* Pseudo Op codes */
|
||||||
static void do_adr PARAMS ((char *operands, unsigned long flags));
|
static void do_adr PARAMS ((char *operands, unsigned long flags));
|
||||||
|
static void do_adrl PARAMS ((char * operands, unsigned long flags));
|
||||||
static void do_nop PARAMS ((char *operands, unsigned long flags));
|
static void do_nop PARAMS ((char *operands, unsigned long flags));
|
||||||
/* ARM 2 */
|
/* ARM 2 */
|
||||||
static void do_mul PARAMS ((char *operands, unsigned long flags));
|
static void do_mul PARAMS ((char *operands, unsigned long flags));
|
||||||
|
@ -455,6 +461,7 @@ static void symbol_locate PARAMS ((symbolS *, CONST char *, segT,
|
||||||
valueT, fragS *));
|
valueT, fragS *));
|
||||||
static int add_to_lit_pool PARAMS ((void));
|
static int add_to_lit_pool PARAMS ((void));
|
||||||
static unsigned validate_immediate PARAMS ((unsigned));
|
static unsigned validate_immediate PARAMS ((unsigned));
|
||||||
|
static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *));
|
||||||
static int validate_offset_imm PARAMS ((int, int));
|
static int validate_offset_imm PARAMS ((int, int));
|
||||||
static void opcode_select PARAMS ((int));
|
static void opcode_select PARAMS ((int));
|
||||||
static void end_of_line PARAMS ((char *));
|
static void end_of_line PARAMS ((char *));
|
||||||
|
@ -484,7 +491,7 @@ static void thumb_mov_compare PARAMS ((char *, int));
|
||||||
static void set_constant_flonums PARAMS ((void));
|
static void set_constant_flonums PARAMS ((void));
|
||||||
static valueT md_chars_to_number PARAMS ((char *, int));
|
static valueT md_chars_to_number PARAMS ((char *, int));
|
||||||
static void insert_reg_alias PARAMS ((char *, int));
|
static void insert_reg_alias PARAMS ((char *, int));
|
||||||
static void output_inst PARAMS ((char *));
|
static void output_inst PARAMS ((void));
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
|
static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
|
||||||
#endif
|
#endif
|
||||||
|
@ -540,6 +547,7 @@ static CONST struct asm_opcode insns[] =
|
||||||
|
|
||||||
/* Pseudo ops */
|
/* Pseudo ops */
|
||||||
{"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
|
{"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
|
||||||
|
{"adrl", 0x028f0000, NULL, NULL, ARM_ANY, do_adrl},
|
||||||
{"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
|
{"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
|
||||||
|
|
||||||
/* ARM 2 multiplies */
|
/* ARM 2 multiplies */
|
||||||
|
@ -1079,6 +1087,47 @@ validate_immediate (val)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check to see if an immediate can be computed as two seperate immediate
|
||||||
|
values, added together. We already know that this value cannot be
|
||||||
|
computed by just one ARM instruction. */
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
validate_immediate_twopart (val, highpart)
|
||||||
|
unsigned int val;
|
||||||
|
unsigned int * highpart;
|
||||||
|
{
|
||||||
|
unsigned int a;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 32; i += 2)
|
||||||
|
if (((a = rotate_left (val, i)) & 0xff) != 0)
|
||||||
|
{
|
||||||
|
if (a & 0xff00)
|
||||||
|
{
|
||||||
|
if (a & ~ 0xffff)
|
||||||
|
continue;
|
||||||
|
* highpart = (a >> 8) | ((i + 24) << 7);
|
||||||
|
}
|
||||||
|
else if (a & 0xff0000)
|
||||||
|
{
|
||||||
|
if (a & 0xff000000)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
* highpart = (a >> 16) | ((i + 16) << 7);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert (a & 0xff000000);
|
||||||
|
|
||||||
|
* highpart = (a >> 24) | ((i + 8) << 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (a & 0xff) | (i << 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
validate_offset_imm (val, hwse)
|
validate_offset_imm (val, hwse)
|
||||||
int val;
|
int val;
|
||||||
|
@ -2606,6 +2655,41 @@ do_adr (str, flags)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_adrl (str, flags)
|
||||||
|
char * str;
|
||||||
|
unsigned long flags;
|
||||||
|
{
|
||||||
|
/* This is a pseudo-op of the form "adrl rd, label" to be converted
|
||||||
|
into a relative address of the form:
|
||||||
|
add rd, pc, #low(label-.-8)"
|
||||||
|
add rd, rd, #high(label-.-8)" */
|
||||||
|
|
||||||
|
while (* str == ' ')
|
||||||
|
str ++;
|
||||||
|
|
||||||
|
if (reg_required_here (& str, 12) == FAIL
|
||||||
|
|| skip_past_comma (& str) == FAIL
|
||||||
|
|| my_get_expression (& inst.reloc.exp, & str))
|
||||||
|
{
|
||||||
|
if (!inst.error)
|
||||||
|
inst.error = bad_args;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
end_of_line (str);
|
||||||
|
|
||||||
|
/* Frag hacking will turn this into a sub instruction if the offset turns
|
||||||
|
out to be negative. */
|
||||||
|
inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
|
||||||
|
inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
|
||||||
|
inst.reloc.pc_rel = 1;
|
||||||
|
inst.instruction |= flags;
|
||||||
|
inst.size = INSN_SIZE * 2;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_cmp (str, flags)
|
do_cmp (str, flags)
|
||||||
char * str;
|
char * str;
|
||||||
|
@ -4984,9 +5068,13 @@ md_begin ()
|
||||||
/* Catch special cases */
|
/* Catch special cases */
|
||||||
if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
|
if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
|
||||||
{
|
{
|
||||||
if (cpu_variant & ARM_THUMB)
|
if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
|
||||||
|
mach = bfd_mach_arm_5T;
|
||||||
|
else if (cpu_variant & ARM_EXT_V5)
|
||||||
|
mach = bfd_mach_arm_5;
|
||||||
|
else if (cpu_variant & ARM_THUMB)
|
||||||
mach = bfd_mach_arm_4T;
|
mach = bfd_mach_arm_4T;
|
||||||
else if ((cpu_variant & ARM_ARCHv4) == ARM_ARCHv4)
|
else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
|
||||||
mach = bfd_mach_arm_4;
|
mach = bfd_mach_arm_4;
|
||||||
else if (cpu_variant & ARM_LONGMUL)
|
else if (cpu_variant & ARM_LONGMUL)
|
||||||
mach = bfd_mach_arm_3M;
|
mach = bfd_mach_arm_3M;
|
||||||
|
@ -5326,6 +5414,50 @@ md_apply_fix3 (fixP, val, seg)
|
||||||
md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
|
md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BFD_RELOC_ARM_ADRL_IMMEDIATE:
|
||||||
|
{
|
||||||
|
unsigned int highpart = 0;
|
||||||
|
unsigned int newinsn = 0xe1a00000; /* nop */
|
||||||
|
newimm = validate_immediate (value);
|
||||||
|
temp = md_chars_to_number (buf, INSN_SIZE);
|
||||||
|
|
||||||
|
/* If the instruction will fail, see if we can fix things up by
|
||||||
|
changing the opcode. */
|
||||||
|
if (newimm == (unsigned int) FAIL
|
||||||
|
&& (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
|
||||||
|
{
|
||||||
|
/* No ? OK - try using two ADD instructions to generate the value. */
|
||||||
|
newimm = validate_immediate_twopart (value, & highpart);
|
||||||
|
|
||||||
|
/* Yes - then make sure that the second instruction is also an add. */
|
||||||
|
if (newimm != (unsigned int) FAIL)
|
||||||
|
newinsn = temp;
|
||||||
|
/* Still No ? Try using a negated value. */
|
||||||
|
else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
|
||||||
|
temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
|
||||||
|
/* Otherwise - give up. */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||||
|
_("Unable to compute ADRL instructions for PC offset of 0x%x\n"), value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace the first operand in the 2nd instruction (which is the PC)
|
||||||
|
with the destination register. We have already added in the PC in the
|
||||||
|
first instruction and we do not want to do it again. */
|
||||||
|
newinsn &= ~ 0xf0000;
|
||||||
|
newinsn |= ((newinsn & 0x0f000) << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
newimm |= (temp & 0xfffff000);
|
||||||
|
md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
|
||||||
|
|
||||||
|
highpart |= (newinsn & 0xfffff000);
|
||||||
|
md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_ARM_OFFSET_IMM:
|
case BFD_RELOC_ARM_OFFSET_IMM:
|
||||||
sign = value >= 0;
|
sign = value >= 0;
|
||||||
if ((value = validate_offset_imm (value, 0)) == FAIL)
|
if ((value = validate_offset_imm (value, 0)) == FAIL)
|
||||||
|
@ -5816,6 +5948,12 @@ tc_gen_reloc (section, fixp)
|
||||||
fixp->fx_r_type);
|
fixp->fx_r_type);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
case BFD_RELOC_ARM_ADRL_IMMEDIATE:
|
||||||
|
as_bad_where (fixp->fx_file, fixp->fx_line,
|
||||||
|
_("ADRL used for a symbol not defined in the same file"),
|
||||||
|
fixp->fx_r_type);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
case BFD_RELOC_ARM_OFFSET_IMM:
|
case BFD_RELOC_ARM_OFFSET_IMM:
|
||||||
as_bad_where (fixp->fx_file, fixp->fx_line,
|
as_bad_where (fixp->fx_file, fixp->fx_line,
|
||||||
_("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
|
_("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
|
||||||
|
@ -5880,8 +6018,7 @@ md_estimate_size_before_relax (fragP, segtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
output_inst (str)
|
output_inst PARAMS ((void))
|
||||||
char * str;
|
|
||||||
{
|
{
|
||||||
char * to = NULL;
|
char * to = NULL;
|
||||||
|
|
||||||
|
@ -5896,7 +6033,13 @@ output_inst (str)
|
||||||
{
|
{
|
||||||
assert (inst.size == (2 * THUMB_SIZE));
|
assert (inst.size == (2 * THUMB_SIZE));
|
||||||
md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
|
md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
|
||||||
md_number_to_chars (to + 2, inst.instruction, THUMB_SIZE);
|
md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
|
||||||
|
}
|
||||||
|
else if (inst.size > INSN_SIZE)
|
||||||
|
{
|
||||||
|
assert (inst.size == (2 * INSN_SIZE));
|
||||||
|
md_number_to_chars (to, inst.instruction, INSN_SIZE);
|
||||||
|
md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
md_number_to_chars (to, inst.instruction, inst.size);
|
md_number_to_chars (to, inst.instruction, inst.size);
|
||||||
|
@ -5957,12 +6100,13 @@ md_assemble (str)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
|
opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
|
||||||
*p = c;
|
*p = c;
|
||||||
|
|
||||||
if (opcode)
|
if (opcode)
|
||||||
{
|
{
|
||||||
inst.instruction = opcode->value;
|
inst.instruction = opcode->value;
|
||||||
inst.size = opcode->size;
|
inst.size = opcode->size;
|
||||||
(*opcode->parms)(p);
|
(*opcode->parms)(p);
|
||||||
output_inst (start);
|
output_inst ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5982,6 +6126,7 @@ md_assemble (str)
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
|
opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
|
||||||
*q = c;
|
*q = c;
|
||||||
|
|
||||||
if (opcode && opcode->template)
|
if (opcode && opcode->template)
|
||||||
{
|
{
|
||||||
unsigned long flag_bits = 0;
|
unsigned long flag_bits = 0;
|
||||||
|
@ -6002,7 +6147,7 @@ md_assemble (str)
|
||||||
inst.instruction |= COND_ALWAYS;
|
inst.instruction |= COND_ALWAYS;
|
||||||
(*opcode->parms)(q, 0);
|
(*opcode->parms)(q, 0);
|
||||||
}
|
}
|
||||||
output_inst (start);
|
output_inst ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6087,7 +6232,7 @@ _("Warning: Use of the 'nv' conditional is deprecated\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
(*opcode->parms) (p, flag_bits);
|
(*opcode->parms) (p, flag_bits);
|
||||||
output_inst (start);
|
output_inst ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6174,9 +6319,10 @@ _("Warning: Use of the 'nv' conditional is deprecated\n"));
|
||||||
* -m[arm]3 Arm 3 processor
|
* -m[arm]3 Arm 3 processor
|
||||||
* -m[arm]6[xx], Arm 6 processors
|
* -m[arm]6[xx], Arm 6 processors
|
||||||
* -m[arm]7[xx][t][[d]m] Arm 7 processors
|
* -m[arm]7[xx][t][[d]m] Arm 7 processors
|
||||||
* -m8[10] Arm 8 processors
|
* -m[arm]8[10] Arm 8 processors
|
||||||
* -m9[20][tdmi] Arm 9 processors
|
* -m[arm]9[20][tdmi] Arm 9 processors
|
||||||
* -mstrongarm[110[0]] StrongARM processors
|
* -mstrongarm[110[0]] StrongARM processors
|
||||||
|
* -m[arm]v[2345] Arm architecures
|
||||||
* -mall All (except the ARM1)
|
* -mall All (except the ARM1)
|
||||||
* FP variants:
|
* FP variants:
|
||||||
* -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
|
* -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
|
||||||
|
@ -6265,7 +6411,7 @@ md_parse_option (c, arg)
|
||||||
}
|
}
|
||||||
else if (streq (str, "thumb-interwork"))
|
else if (streq (str, "thumb-interwork"))
|
||||||
{
|
{
|
||||||
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCHv4;
|
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCH_V4;
|
||||||
#if defined OBJ_COFF || defined OBJ_ELF
|
#if defined OBJ_COFF || defined OBJ_ELF
|
||||||
support_interwork = true;
|
support_interwork = true;
|
||||||
#endif
|
#endif
|
||||||
|
@ -6399,7 +6545,7 @@ md_parse_option (c, arg)
|
||||||
switch (* str)
|
switch (* str)
|
||||||
{
|
{
|
||||||
case 't':
|
case 't':
|
||||||
cpu_variant |= (ARM_THUMB | ARM_ARCHv4);
|
cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
|
@ -6426,20 +6572,20 @@ md_parse_option (c, arg)
|
||||||
|
|
||||||
case '8':
|
case '8':
|
||||||
if (streq (str, "8") || streq (str, "810"))
|
if (streq (str, "8") || streq (str, "810"))
|
||||||
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL;
|
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
|
||||||
else
|
else
|
||||||
goto bad;
|
goto bad;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '9':
|
case '9':
|
||||||
if (streq (str, "9"))
|
if (streq (str, "9"))
|
||||||
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL | ARM_THUMB;
|
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
|
||||||
else if (streq (str, "920"))
|
else if (streq (str, "920"))
|
||||||
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL;
|
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
|
||||||
else if (streq (str, "920t"))
|
else if (streq (str, "920t"))
|
||||||
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL | ARM_THUMB;
|
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
|
||||||
else if (streq (str, "9tdmi"))
|
else if (streq (str, "9tdmi"))
|
||||||
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL | ARM_THUMB;
|
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
|
||||||
else
|
else
|
||||||
goto bad;
|
goto bad;
|
||||||
break;
|
break;
|
||||||
|
@ -6448,7 +6594,7 @@ md_parse_option (c, arg)
|
||||||
if (streq (str, "strongarm")
|
if (streq (str, "strongarm")
|
||||||
|| streq (str, "strongarm110")
|
|| streq (str, "strongarm110")
|
||||||
|| streq (str, "strongarm1100"))
|
|| streq (str, "strongarm1100"))
|
||||||
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL;
|
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
|
||||||
else
|
else
|
||||||
goto bad;
|
goto bad;
|
||||||
break;
|
break;
|
||||||
|
@ -6478,7 +6624,18 @@ md_parse_option (c, arg)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '4':
|
case '4':
|
||||||
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCHv4;
|
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
|
||||||
|
|
||||||
|
switch (*++str)
|
||||||
|
{
|
||||||
|
case 't': cpu_variant |= ARM_THUMB; break;
|
||||||
|
case 0: break;
|
||||||
|
default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '5':
|
||||||
|
cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
|
||||||
|
|
||||||
switch (*++str)
|
switch (*++str)
|
||||||
{
|
{
|
||||||
|
@ -6521,7 +6678,7 @@ md_show_usage (fp)
|
||||||
_("\
|
_("\
|
||||||
ARM Specific Assembler Options:\n\
|
ARM Specific Assembler Options:\n\
|
||||||
-m[arm][<processor name>] select processor variant\n\
|
-m[arm][<processor name>] select processor variant\n\
|
||||||
-m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
|
-m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
|
||||||
-mthumb only allow Thumb instructions\n\
|
-mthumb only allow Thumb instructions\n\
|
||||||
-mthumb-interwork mark the assembled code as supporting interworking\n\
|
-mthumb-interwork mark the assembled code as supporting interworking\n\
|
||||||
-mall allow any instruction\n\
|
-mall allow any instruction\n\
|
||||||
|
|
|
@ -29,12 +29,12 @@
|
||||||
@cindex options for ARM (none)
|
@cindex options for ARM (none)
|
||||||
@table @code
|
@table @code
|
||||||
@cindex @code{-marm} command line option, ARM
|
@cindex @code{-marm} command line option, ARM
|
||||||
@item -marm @var{[2|250|3|6|60|600|610|620|7|7m|7d|7dm|7di|7dmi|70|700|700i|710|710c|7100|7500|7500fe|7tdmi|8|810|9|9tdmistrongarm|strongarm110|strongarm1100]}
|
@item -marm @var{[2|250|3|6|60|600|610|620|7|7m|7d|7dm|7di|7dmi|70|700|700i|710|710c|7100|7500|7500fe|7tdmi|8|810|9|9tdmi|920||strongarm|strongarm110|strongarm1100]}
|
||||||
This option specifies the target processor. The assembler will issue an
|
This option specifies the target processor. The assembler will issue an
|
||||||
error message if an attempt is made to assemble an instruction which
|
error message if an attempt is made to assemble an instruction which
|
||||||
will not execute on the target processor.
|
will not execute on the target processor.
|
||||||
@cindex @code{-marmv} command line option, ARM
|
@cindex @code{-marmv} command line option, ARM
|
||||||
@item -marmv @var{[2|2a|3|3m|4|4t]}
|
@item -marmv @var{[2|2a|3|3m|4|4t|5|5t]}
|
||||||
This option specifies the target architecture. The assembler will issue
|
This option specifies the target architecture. The assembler will issue
|
||||||
an error message if an attempt is made to assemble an instruction which
|
an error message if an attempt is made to assemble an instruction which
|
||||||
will not execute on the target architecture.
|
will not execute on the target architecture.
|
||||||
|
@ -184,13 +184,23 @@ This is a synonym for .ltorg.
|
||||||
|
|
||||||
@cindex ARM opcodes
|
@cindex ARM opcodes
|
||||||
@cindex opcodes for ARM
|
@cindex opcodes for ARM
|
||||||
@code{@value{AS}} implements all the standard ARM opcodes.
|
@code{@value{AS}} implements all the standard ARM opcodes. It also
|
||||||
|
implements several pseudo opcodes, including several synthetic load
|
||||||
|
instructions.
|
||||||
|
|
||||||
*TODO* Document the pseudo-ops (adr, nop)
|
@table @code
|
||||||
|
|
||||||
GAS for the ARM supports a synthetic register load instruction whoes
|
@cindex @code{NOP} pseudo op, ARM
|
||||||
syntax is:
|
@item NOP
|
||||||
|
@smallexample
|
||||||
|
nop
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
This pseudo op will always evaluate to a legal ARM instruction that does
|
||||||
|
nothing. Currently it will evaluate to MOV r0, r0.
|
||||||
|
|
||||||
|
@cindex @code{LDR reg,=<label>} pseudo op, ARM
|
||||||
|
@item LDR
|
||||||
@smallexample
|
@smallexample
|
||||||
ldr <register> , = <expression>
|
ldr <register> , = <expression>
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
@ -201,6 +211,37 @@ constant can be generated by either of these instructions. Otherwise
|
||||||
the constant will be placed into the nearest literal pool (if it not
|
the constant will be placed into the nearest literal pool (if it not
|
||||||
already there) and a PC relative LDR instruction will be generated.
|
already there) and a PC relative LDR instruction will be generated.
|
||||||
|
|
||||||
|
@cindex @code{ADR reg,<label>} pseudo op, ARM
|
||||||
|
@item ADR
|
||||||
|
@smallexample
|
||||||
|
adr <register> <label>
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
This instruction will load the address of @var{label} into the indicated
|
||||||
|
register. The instruction will evaluate to a PC relative ADD or SUB
|
||||||
|
instruction depending upon where the label is located. If the label is
|
||||||
|
out of range, or if it is not defined in the same file (and section) as
|
||||||
|
the ADR instruction, then an error will be generated. This instruction
|
||||||
|
will not make use of the literal pool.
|
||||||
|
|
||||||
|
@cindex @code{ADRL reg,<label>} pseudo op, ARM
|
||||||
|
@item ADRL
|
||||||
|
@smallexample
|
||||||
|
adrl <register> <label>
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
This instruction will load the address of @var{label} into the indicated
|
||||||
|
register. The instruction will evaluate to one or two a PC relative ADD
|
||||||
|
or SUB instructions depending upon where the label is located. If a
|
||||||
|
second instruction is not needed a NOP instruction will be generated in
|
||||||
|
its place, so that this instruction is always 8 bytes long.
|
||||||
|
|
||||||
|
If the label is out of range, or if it is not defined in the same file
|
||||||
|
(and section) as the ADRL instruction, then an error will be generated.
|
||||||
|
This instruction will not make use of the literal pool.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
For information on the ARM or Thumb instruction sets, see @cite{ARM
|
For information on the ARM or Thumb instruction sets, see @cite{ARM
|
||||||
Software Development Toolkit Reference Manual}, Advanced RISC Machines
|
Software Development Toolkit Reference Manual}, Advanced RISC Machines
|
||||||
Ltd.
|
Ltd.
|
||||||
|
|
Loading…
Reference in New Issue