mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-26 21:40:38 +00:00
Add support for armv5 architecture
Add ADRL pseudo op.
This commit is contained in:
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)
|
||||
|
||||
* 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_HALFWORD 0x00000020 /* allow half word loads */
|
||||
#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: */
|
||||
#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_3UP 0x00fffffc
|
||||
#define ARM_6UP 0x00fffff8 /* Includes ARM7 */
|
||||
@ -73,7 +78,7 @@
|
||||
|
||||
#ifndef CPU_DEFAULT
|
||||
#if defined __thumb__
|
||||
#define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
|
||||
#define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
|
||||
#else
|
||||
#define CPU_DEFAULT ARM_ALL
|
||||
#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));
|
||||
/* Pseudo Op codes */
|
||||
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));
|
||||
/* ARM 2 */
|
||||
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 *));
|
||||
static int add_to_lit_pool PARAMS ((void));
|
||||
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 void opcode_select PARAMS ((int));
|
||||
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 valueT md_chars_to_number 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
|
||||
static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
|
||||
#endif
|
||||
@ -540,6 +547,7 @@ static CONST struct asm_opcode insns[] =
|
||||
|
||||
/* Pseudo ops */
|
||||
{"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
|
||||
{"adrl", 0x028f0000, NULL, NULL, ARM_ANY, do_adrl},
|
||||
{"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
|
||||
|
||||
/* ARM 2 multiplies */
|
||||
@ -870,8 +878,8 @@ static CONST struct reg_entry reg_table[] =
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
#define bad_args _("Bad arguments to instruction");
|
||||
#define bad_pc _("r15 not allowed here");
|
||||
#define bad_args _("Bad arguments to instruction");
|
||||
#define bad_pc _("r15 not allowed here");
|
||||
|
||||
static struct hash_control * arm_ops_hsh = NULL;
|
||||
static struct hash_control * arm_tops_hsh = NULL;
|
||||
@ -1079,6 +1087,47 @@ validate_immediate (val)
|
||||
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
|
||||
validate_offset_imm (val, hwse)
|
||||
int val;
|
||||
@ -2606,6 +2655,41 @@ do_adr (str, flags)
|
||||
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
|
||||
do_cmp (str, flags)
|
||||
char * str;
|
||||
@ -4984,9 +5068,13 @@ md_begin ()
|
||||
/* Catch special cases */
|
||||
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;
|
||||
else if ((cpu_variant & ARM_ARCHv4) == ARM_ARCHv4)
|
||||
else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
|
||||
mach = bfd_mach_arm_4;
|
||||
else if (cpu_variant & ARM_LONGMUL)
|
||||
mach = bfd_mach_arm_3M;
|
||||
@ -5326,7 +5414,51 @@ md_apply_fix3 (fixP, val, seg)
|
||||
md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_ARM_OFFSET_IMM:
|
||||
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:
|
||||
sign = value >= 0;
|
||||
if ((value = validate_offset_imm (value, 0)) == FAIL)
|
||||
{
|
||||
@ -5816,6 +5948,12 @@ tc_gen_reloc (section, fixp)
|
||||
fixp->fx_r_type);
|
||||
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:
|
||||
as_bad_where (fixp->fx_file, fixp->fx_line,
|
||||
_("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
|
||||
@ -5880,8 +6018,7 @@ md_estimate_size_before_relax (fragP, segtype)
|
||||
}
|
||||
|
||||
static void
|
||||
output_inst (str)
|
||||
char * str;
|
||||
output_inst PARAMS ((void))
|
||||
{
|
||||
char * to = NULL;
|
||||
|
||||
@ -5896,7 +6033,13 @@ output_inst (str)
|
||||
{
|
||||
assert (inst.size == (2 * 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
|
||||
md_number_to_chars (to, inst.instruction, inst.size);
|
||||
@ -5936,7 +6079,7 @@ md_assemble (str)
|
||||
|
||||
if (*str == ' ')
|
||||
str++; /* Skip leading white space */
|
||||
|
||||
|
||||
/* Scan up to the end of the op-code, which must end in white space or
|
||||
end of string. */
|
||||
for (start = p = str; *p != '\0'; p++)
|
||||
@ -5951,24 +6094,25 @@ md_assemble (str)
|
||||
|
||||
if (thumb_mode)
|
||||
{
|
||||
CONST struct thumb_opcode *opcode;
|
||||
CONST struct thumb_opcode * opcode;
|
||||
|
||||
c = *p;
|
||||
*p = '\0';
|
||||
opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
|
||||
*p = c;
|
||||
|
||||
if (opcode)
|
||||
{
|
||||
inst.instruction = opcode->value;
|
||||
inst.size = opcode->size;
|
||||
(*opcode->parms)(p);
|
||||
output_inst (start);
|
||||
output_inst ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CONST struct asm_opcode *opcode;
|
||||
CONST struct asm_opcode * opcode;
|
||||
|
||||
inst.size = INSN_SIZE;
|
||||
/* p now points to the end of the opcode, probably white space, but we
|
||||
@ -5982,10 +6126,11 @@ md_assemble (str)
|
||||
*q = '\0';
|
||||
opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
|
||||
*q = c;
|
||||
|
||||
if (opcode && opcode->template)
|
||||
{
|
||||
unsigned long flag_bits = 0;
|
||||
char *r;
|
||||
char * r;
|
||||
|
||||
/* Check that this instruction is supported for this CPU */
|
||||
if ((opcode->variants & cpu_variant) == 0)
|
||||
@ -6002,7 +6147,7 @@ md_assemble (str)
|
||||
inst.instruction |= COND_ALWAYS;
|
||||
(*opcode->parms)(q, 0);
|
||||
}
|
||||
output_inst (start);
|
||||
output_inst ();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6087,7 +6232,7 @@ _("Warning: Use of the 'nv' conditional is deprecated\n"));
|
||||
}
|
||||
|
||||
(*opcode->parms) (p, flag_bits);
|
||||
output_inst (start);
|
||||
output_inst ();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6174,9 +6319,10 @@ _("Warning: Use of the 'nv' conditional is deprecated\n"));
|
||||
* -m[arm]3 Arm 3 processor
|
||||
* -m[arm]6[xx], Arm 6 processors
|
||||
* -m[arm]7[xx][t][[d]m] Arm 7 processors
|
||||
* -m8[10] Arm 8 processors
|
||||
* -m9[20][tdmi] Arm 9 processors
|
||||
* -m[arm]8[10] Arm 8 processors
|
||||
* -m[arm]9[20][tdmi] Arm 9 processors
|
||||
* -mstrongarm[110[0]] StrongARM processors
|
||||
* -m[arm]v[2345] Arm architecures
|
||||
* -mall All (except the ARM1)
|
||||
* FP variants:
|
||||
* -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
|
||||
@ -6265,7 +6411,7 @@ md_parse_option (c, arg)
|
||||
}
|
||||
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
|
||||
support_interwork = true;
|
||||
#endif
|
||||
@ -6399,7 +6545,7 @@ md_parse_option (c, arg)
|
||||
switch (* str)
|
||||
{
|
||||
case 't':
|
||||
cpu_variant |= (ARM_THUMB | ARM_ARCHv4);
|
||||
cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
@ -6426,20 +6572,20 @@ md_parse_option (c, arg)
|
||||
|
||||
case '8':
|
||||
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
|
||||
goto bad;
|
||||
break;
|
||||
|
||||
case '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"))
|
||||
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"))
|
||||
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"))
|
||||
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
|
||||
goto bad;
|
||||
break;
|
||||
@ -6448,7 +6594,7 @@ md_parse_option (c, arg)
|
||||
if (streq (str, "strongarm")
|
||||
|| streq (str, "strongarm110")
|
||||
|| 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
|
||||
goto bad;
|
||||
break;
|
||||
@ -6478,7 +6624,18 @@ md_parse_option (c, arg)
|
||||
break;
|
||||
|
||||
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)
|
||||
{
|
||||
@ -6521,7 +6678,7 @@ md_show_usage (fp)
|
||||
_("\
|
||||
ARM Specific Assembler Options:\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-interwork mark the assembled code as supporting interworking\n\
|
||||
-mall allow any instruction\n\
|
||||
|
@ -29,12 +29,12 @@
|
||||
@cindex options for ARM (none)
|
||||
@table @code
|
||||
@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
|
||||
error message if an attempt is made to assemble an instruction which
|
||||
will not execute on the target processor.
|
||||
@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
|
||||
an error message if an attempt is made to assemble an instruction which
|
||||
will not execute on the target architecture.
|
||||
@ -184,13 +184,23 @@ This is a synonym for .ltorg.
|
||||
|
||||
@cindex ARM opcodes
|
||||
@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
|
||||
syntax is:
|
||||
@cindex @code{NOP} pseudo op, ARM
|
||||
@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
|
||||
ldr <register> , = <expression>
|
||||
@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
|
||||
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
|
||||
Software Development Toolkit Reference Manual}, Advanced RISC Machines
|
||||
Ltd.
|
||||
|
Loading…
Reference in New Issue
Block a user