Line 349... |
Line 349... |
NEUTRAL_IT_INSN, /* This could be either inside or outside,
|
NEUTRAL_IT_INSN, /* This could be either inside or outside,
|
i.e. BKPT and NOP. */
|
i.e. BKPT and NOP. */
|
IT_INSN /* The IT insn has been parsed. */
|
IT_INSN /* The IT insn has been parsed. */
|
};
|
};
|
|
|
|
/* The maximum number of operands we need. */
|
|
#define ARM_IT_MAX_OPERANDS 6
|
|
|
struct arm_it
|
struct arm_it
|
{
|
{
|
const char * error;
|
const char * error;
|
unsigned long instruction;
|
unsigned long instruction;
|
int size;
|
int size;
|
Line 400... |
Line 403... |
unsigned preind : 1; /* Preindexed address. */
|
unsigned preind : 1; /* Preindexed address. */
|
unsigned postind : 1; /* Postindexed address. */
|
unsigned postind : 1; /* Postindexed address. */
|
unsigned negative : 1; /* Index register was negated. */
|
unsigned negative : 1; /* Index register was negated. */
|
unsigned shifted : 1; /* Shift applied to operation. */
|
unsigned shifted : 1; /* Shift applied to operation. */
|
unsigned shift_kind : 3; /* Shift operation (enum shift_kind). */
|
unsigned shift_kind : 3; /* Shift operation (enum shift_kind). */
|
} operands[6];
|
} operands[ARM_IT_MAX_OPERANDS];
|
};
|
};
|
|
|
static struct arm_it inst;
|
static struct arm_it inst;
|
|
|
#define NUM_FLOAT_VALS 8
|
#define NUM_FLOAT_VALS 8
|
Line 558... |
Line 561... |
N_("iWMMXt scalar register expected"),
|
N_("iWMMXt scalar register expected"),
|
N_("XScale accumulator register expected"),
|
N_("XScale accumulator register expected"),
|
};
|
};
|
|
|
/* Some well known registers that we refer to directly elsewhere. */
|
/* Some well known registers that we refer to directly elsewhere. */
|
|
#define REG_R12 12
|
#define REG_SP 13
|
#define REG_SP 13
|
#define REG_LR 14
|
#define REG_LR 14
|
#define REG_PC 15
|
#define REG_PC 15
|
|
|
/* ARM instructions take 4bytes in the object file, Thumb instructions
|
/* ARM instructions take 4bytes in the object file, Thumb instructions
|
Line 3534... |
Line 3538... |
start_unwind_section (unwind.saved_seg, 1);
|
start_unwind_section (unwind.saved_seg, 1);
|
frag_align (2, 0, 0);
|
frag_align (2, 0, 0);
|
record_alignment (now_seg, 2);
|
record_alignment (now_seg, 2);
|
|
|
ptr = frag_more (8);
|
ptr = frag_more (8);
|
|
memset (ptr, 0, 8);
|
where = frag_now_fix () - 8;
|
where = frag_now_fix () - 8;
|
|
|
/* Self relative offset of the function start. */
|
/* Self relative offset of the function start. */
|
fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
|
fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
|
BFD_RELOC_ARM_PREL31);
|
BFD_RELOC_ARM_PREL31);
|
Line 5929... |
Line 5934... |
if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
|
if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
|
goto wanted_arm;
|
goto wanted_arm;
|
|
|
inst.operands[i].reg = val;
|
inst.operands[i].reg = val;
|
inst.operands[i].isreg = 1;
|
inst.operands[i].isreg = 1;
|
inst.operands[i++].present = 1;
|
inst.operands[i].present = 1;
|
}
|
}
|
}
|
}
|
else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
|
else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
|
/* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
|
/* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
|
Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
|
Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
|
Line 6019... |
Line 6024... |
inst.operands[i].reg = val;
|
inst.operands[i].reg = val;
|
inst.operands[i].isreg = 1;
|
inst.operands[i].isreg = 1;
|
inst.operands[i].isvec = 1;
|
inst.operands[i].isvec = 1;
|
inst.operands[i].issingle = 1;
|
inst.operands[i].issingle = 1;
|
inst.operands[i].vectype = optype;
|
inst.operands[i].vectype = optype;
|
inst.operands[i++].present = 1;
|
inst.operands[i].present = 1;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
first_error (_("parse error"));
|
first_error (_("parse error"));
|
Line 10649... |
Line 10654... |
if (!inst.operands[1].present)
|
if (!inst.operands[1].present)
|
{
|
{
|
inst.operands[1].reg = inst.operands[0].reg + 1;
|
inst.operands[1].reg = inst.operands[0].reg + 1;
|
constraint (inst.operands[0].reg == REG_LR,
|
constraint (inst.operands[0].reg == REG_LR,
|
_("r14 not allowed here"));
|
_("r14 not allowed here"));
|
|
constraint (inst.operands[0].reg == REG_R12,
|
|
_("r12 not allowed here"));
|
}
|
}
|
|
|
|
if (inst.operands[2].writeback
|
|
&& (inst.operands[0].reg == inst.operands[2].reg
|
|
|| inst.operands[1].reg == inst.operands[2].reg))
|
|
as_warn (_("base register written back, and overlaps "
|
|
"one of transfer registers"));
|
|
|
inst.instruction |= inst.operands[0].reg << 12;
|
inst.instruction |= inst.operands[0].reg << 12;
|
inst.instruction |= inst.operands[1].reg << 8;
|
inst.instruction |= inst.operands[1].reg << 8;
|
encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
|
encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
|
}
|
}
|
|
|
Line 10911... |
Line 10925... |
}
|
}
|
else
|
else
|
switch (inst.instruction)
|
switch (inst.instruction)
|
{
|
{
|
case T_MNEM_mov:
|
case T_MNEM_mov:
|
|
/* In v4t or v5t a move of two lowregs produces unpredictable
|
|
results. Don't allow this. */
|
|
if (low_regs)
|
|
{
|
|
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
|
|
"MOV Rd, Rs with two low registers is not "
|
|
"permitted on this architecture");
|
|
ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
|
|
arm_ext_v6);
|
|
}
|
|
|
inst.instruction = T_OPCODE_MOV_HR;
|
inst.instruction = T_OPCODE_MOV_HR;
|
inst.instruction |= (Rn & 0x8) << 4;
|
inst.instruction |= (Rn & 0x8) << 4;
|
inst.instruction |= (Rn & 0x7);
|
inst.instruction |= (Rn & 0x7);
|
inst.instruction |= Rm << 3;
|
inst.instruction |= Rm << 3;
|
break;
|
break;
|
Line 12402... |
Line 12427... |
break;
|
break;
|
}
|
}
|
if (!matches)
|
if (!matches)
|
break;
|
break;
|
}
|
}
|
if (matches)
|
if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
|
|
/* We've matched all the entries in the shape table, and we don't
|
|
have any left over operands which have not been matched. */
|
break;
|
break;
|
}
|
}
|
|
|
va_end (ap);
|
va_end (ap);
|
|
|
Line 19898... |
Line 19925... |
else
|
else
|
/* We get two opcodes "free" in the first word. */
|
/* We get two opcodes "free" in the first word. */
|
size = unwind.opcode_count - 2;
|
size = unwind.opcode_count - 2;
|
}
|
}
|
else
|
else
|
|
{
|
|
gas_assert (unwind.personality_index == -1);
|
|
|
/* An extra byte is required for the opcode count. */
|
/* An extra byte is required for the opcode count. */
|
size = unwind.opcode_count + 1;
|
size = unwind.opcode_count + 1;
|
|
}
|
|
|
size = (size + 3) >> 2;
|
size = (size + 3) >> 2;
|
if (size > 0xff)
|
if (size > 0xff)
|
as_bad (_("too many unwind opcodes"));
|
as_bad (_("too many unwind opcodes"));
|
|
|
Line 19911... |
Line 19942... |
record_alignment (now_seg, 2);
|
record_alignment (now_seg, 2);
|
unwind.table_entry = expr_build_dot ();
|
unwind.table_entry = expr_build_dot ();
|
|
|
/* Allocate the table entry. */
|
/* Allocate the table entry. */
|
ptr = frag_more ((size << 2) + 4);
|
ptr = frag_more ((size << 2) + 4);
|
|
/* PR 13449: Zero the table entries in case some of them are not used. */
|
|
memset (ptr, 0, (size << 2) + 4);
|
where = frag_now_fix () - ((size << 2) + 4);
|
where = frag_now_fix () - ((size << 2) + 4);
|
|
|
switch (unwind.personality_index)
|
switch (unwind.personality_index)
|
{
|
{
|
case -1:
|
case -1:
|
Line 19925... |
Line 19958... |
|
|
where += 4;
|
where += 4;
|
ptr += 4;
|
ptr += 4;
|
|
|
/* Set the first byte to the number of additional words. */
|
/* Set the first byte to the number of additional words. */
|
data = size - 1;
|
data = size > 0 ? size - 1 : 0;
|
n = 3;
|
n = 3;
|
break;
|
break;
|
|
|
/* ABI defined personality routines. */
|
/* ABI defined personality routines. */
|
case 0:
|
case 0:
|
Line 22861... |
Line 22894... |
};
|
};
|
|
|
struct arm_cpu_option_table
|
struct arm_cpu_option_table
|
{
|
{
|
char *name;
|
char *name;
|
|
size_t name_len;
|
const arm_feature_set value;
|
const arm_feature_set value;
|
/* For some CPUs we assume an FPU unless the user explicitly sets
|
/* For some CPUs we assume an FPU unless the user explicitly sets
|
-mfpu=... */
|
-mfpu=... */
|
const arm_feature_set default_fpu;
|
const arm_feature_set default_fpu;
|
/* The canonical name of the CPU, or NULL to use NAME converted to upper
|
/* The canonical name of the CPU, or NULL to use NAME converted to upper
|
Line 22872... |
Line 22906... |
const char *canonical_name;
|
const char *canonical_name;
|
};
|
};
|
|
|
/* This list should, at a minimum, contain all the cpu names
|
/* This list should, at a minimum, contain all the cpu names
|
recognized by GCC. */
|
recognized by GCC. */
|
|
#define ARM_CPU_OPT(N, V, DF, CN) { N, sizeof (N) - 1, V, DF, CN }
|
static const struct arm_cpu_option_table arm_cpus[] =
|
static const struct arm_cpu_option_table arm_cpus[] =
|
{
|
{
|
{"all", ARM_ANY, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("all", ARM_ANY, FPU_ARCH_FPA, NULL),
|
{"arm1", ARM_ARCH_V1, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm1", ARM_ARCH_V1, FPU_ARCH_FPA, NULL),
|
{"arm2", ARM_ARCH_V2, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm2", ARM_ARCH_V2, FPU_ARCH_FPA, NULL),
|
{"arm250", ARM_ARCH_V2S, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm250", ARM_ARCH_V2S, FPU_ARCH_FPA, NULL),
|
{"arm3", ARM_ARCH_V2S, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm3", ARM_ARCH_V2S, FPU_ARCH_FPA, NULL),
|
{"arm6", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm6", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm60", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm60", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm600", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm600", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm610", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm610", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm620", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm620", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm7", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA, NULL),
|
{"arm7d", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7d", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA, NULL),
|
{"arm7di", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7di", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA, NULL),
|
{"arm70", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm70", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm700", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm700", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm700i", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm700i", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm710", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm710", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm720", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm720", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm710c", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm710c", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm7100", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7100", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm7500", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7500", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA, NULL),
|
{"arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm7tdmi-s", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm7tdmi-s", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm8", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm8", ARM_ARCH_V4, FPU_ARCH_FPA, NULL),
|
{"arm810", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm810", ARM_ARCH_V4, FPU_ARCH_FPA, NULL),
|
{"strongarm", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("strongarm", ARM_ARCH_V4, FPU_ARCH_FPA, NULL),
|
{"strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA, NULL),
|
{"strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA, NULL),
|
{"strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA, NULL),
|
{"strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA, NULL),
|
{"arm9", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm9", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm920", ARM_ARCH_V4T, FPU_ARCH_FPA, "ARM920T"},
|
ARM_CPU_OPT ("arm920", ARM_ARCH_V4T, FPU_ARCH_FPA, "ARM920T"),
|
{"arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL),
|
{"fa526", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("fa526", ARM_ARCH_V4, FPU_ARCH_FPA, NULL),
|
{"fa626", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
|
ARM_CPU_OPT ("fa626", ARM_ARCH_V4, FPU_ARCH_FPA, NULL),
|
/* For V5 or later processors we default to using VFP; but the user
|
/* For V5 or later processors we default to using VFP; but the user
|
should really set the FPU type explicitly. */
|
should really set the FPU type explicitly. */
|
{"arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL),
|
{"arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"arm926ej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, "ARM926EJ-S"},
|
ARM_CPU_OPT ("arm926ej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, "ARM926EJ-S"),
|
{"arm926ejs", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, "ARM926EJ-S"},
|
ARM_CPU_OPT ("arm926ejs", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, "ARM926EJ-S"),
|
{"arm926ej-s", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm926ej-s", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, NULL),
|
{"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL),
|
{"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM946E-S"},
|
ARM_CPU_OPT ("arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM946E-S"),
|
{"arm946e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm946e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL),
|
{"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM966E-S"},
|
ARM_CPU_OPT ("arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM966E-S"),
|
{"arm966e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm966e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"arm968e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm968e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL},
|
ARM_CPU_OPT ("arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL),
|
{"arm10tdmi", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL},
|
ARM_CPU_OPT ("arm10tdmi", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL),
|
{"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM1020E"},
|
ARM_CPU_OPT ("arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM1020E"),
|
{"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL},
|
ARM_CPU_OPT ("arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL),
|
{"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"arm1022e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm1022e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"arm1026ejs", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, "ARM1026EJ-S"},
|
ARM_CPU_OPT ("arm1026ejs", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2,
|
{"arm1026ej-s", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, NULL},
|
"ARM1026EJ-S"),
|
{"fa606te", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm1026ej-s", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, NULL),
|
{"fa616te", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("fa606te", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"fa626te", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("fa616te", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"fmp626", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("fa626te", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"fa726te", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("fmp626", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"arm1136js", ARM_ARCH_V6, FPU_NONE, "ARM1136J-S"},
|
ARM_CPU_OPT ("fa726te", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL),
|
{"arm1136j-s", ARM_ARCH_V6, FPU_NONE, NULL},
|
ARM_CPU_OPT ("arm1136js", ARM_ARCH_V6, FPU_NONE, "ARM1136J-S"),
|
{"arm1136jfs", ARM_ARCH_V6, FPU_ARCH_VFP_V2, "ARM1136JF-S"},
|
ARM_CPU_OPT ("arm1136j-s", ARM_ARCH_V6, FPU_NONE, NULL),
|
{"arm1136jf-s", ARM_ARCH_V6, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm1136jfs", ARM_ARCH_V6, FPU_ARCH_VFP_V2,
|
{"mpcore", ARM_ARCH_V6K, FPU_ARCH_VFP_V2, "MPCore"},
|
"ARM1136JF-S"),
|
{"mpcorenovfp", ARM_ARCH_V6K, FPU_NONE, "MPCore"},
|
ARM_CPU_OPT ("arm1136jf-s", ARM_ARCH_V6, FPU_ARCH_VFP_V2, NULL),
|
{"arm1156t2-s", ARM_ARCH_V6T2, FPU_NONE, NULL},
|
ARM_CPU_OPT ("mpcore", ARM_ARCH_V6K, FPU_ARCH_VFP_V2, "MPCore"),
|
{"arm1156t2f-s", ARM_ARCH_V6T2, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("mpcorenovfp", ARM_ARCH_V6K, FPU_NONE, "MPCore"),
|
{"arm1176jz-s", ARM_ARCH_V6ZK, FPU_NONE, NULL},
|
ARM_CPU_OPT ("arm1156t2-s", ARM_ARCH_V6T2, FPU_NONE, NULL),
|
{"arm1176jzf-s", ARM_ARCH_V6ZK, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("arm1156t2f-s", ARM_ARCH_V6T2, FPU_ARCH_VFP_V2, NULL),
|
{"cortex-a5", ARM_ARCH_V7A_MP_SEC,
|
ARM_CPU_OPT ("arm1176jz-s", ARM_ARCH_V6ZK, FPU_NONE, NULL),
|
FPU_NONE, "Cortex-A5"},
|
ARM_CPU_OPT ("arm1176jzf-s", ARM_ARCH_V6ZK, FPU_ARCH_VFP_V2, NULL),
|
{"cortex-a7", ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
|
ARM_CPU_OPT ("cortex-a5", ARM_ARCH_V7A_MP_SEC,
|
|
FPU_NONE, "Cortex-A5"),
|
|
ARM_CPU_OPT ("cortex-a7", ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
|
FPU_ARCH_NEON_VFP_V4,
|
FPU_ARCH_NEON_VFP_V4,
|
"Cortex-A7"},
|
"Cortex-A7"),
|
{"cortex-a8", ARM_ARCH_V7A_SEC,
|
ARM_CPU_OPT ("cortex-a8", ARM_ARCH_V7A_SEC,
|
ARM_FEATURE (0, FPU_VFP_V3
|
ARM_FEATURE (0, FPU_VFP_V3
|
| FPU_NEON_EXT_V1),
|
| FPU_NEON_EXT_V1),
|
"Cortex-A8"},
|
"Cortex-A8"),
|
{"cortex-a9", ARM_ARCH_V7A_MP_SEC,
|
ARM_CPU_OPT ("cortex-a9", ARM_ARCH_V7A_MP_SEC,
|
ARM_FEATURE (0, FPU_VFP_V3
|
ARM_FEATURE (0, FPU_VFP_V3
|
| FPU_NEON_EXT_V1),
|
| FPU_NEON_EXT_V1),
|
"Cortex-A9"},
|
"Cortex-A9"),
|
{"cortex-a15", ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
|
ARM_CPU_OPT ("cortex-a15", ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
|
FPU_ARCH_NEON_VFP_V4,
|
FPU_ARCH_NEON_VFP_V4,
|
"Cortex-A15"},
|
"Cortex-A15"),
|
{"cortex-r4", ARM_ARCH_V7R, FPU_NONE, "Cortex-R4"},
|
ARM_CPU_OPT ("cortex-r4", ARM_ARCH_V7R, FPU_NONE, "Cortex-R4"),
|
{"cortex-r4f", ARM_ARCH_V7R, FPU_ARCH_VFP_V3D16,
|
ARM_CPU_OPT ("cortex-r4f", ARM_ARCH_V7R, FPU_ARCH_VFP_V3D16,
|
"Cortex-R4F"},
|
"Cortex-R4F"),
|
{"cortex-r5", ARM_ARCH_V7R_IDIV,
|
ARM_CPU_OPT ("cortex-r5", ARM_ARCH_V7R_IDIV,
|
FPU_NONE, "Cortex-R5"},
|
FPU_NONE, "Cortex-R5"),
|
{"cortex-m4", ARM_ARCH_V7EM, FPU_NONE, "Cortex-M4"},
|
ARM_CPU_OPT ("cortex-m4", ARM_ARCH_V7EM, FPU_NONE, "Cortex-M4"),
|
{"cortex-m3", ARM_ARCH_V7M, FPU_NONE, "Cortex-M3"},
|
ARM_CPU_OPT ("cortex-m3", ARM_ARCH_V7M, FPU_NONE, "Cortex-M3"),
|
{"cortex-m1", ARM_ARCH_V6SM, FPU_NONE, "Cortex-M1"},
|
ARM_CPU_OPT ("cortex-m1", ARM_ARCH_V6SM, FPU_NONE, "Cortex-M1"),
|
{"cortex-m0", ARM_ARCH_V6SM, FPU_NONE, "Cortex-M0"},
|
ARM_CPU_OPT ("cortex-m0", ARM_ARCH_V6SM, FPU_NONE, "Cortex-M0"),
|
/* ??? XSCALE is really an architecture. */
|
/* ??? XSCALE is really an architecture. */
|
{"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL),
|
/* ??? iwmmxt is not a processor. */
|
/* ??? iwmmxt is not a processor. */
|
{"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2, NULL),
|
{"iwmmxt2", ARM_ARCH_IWMMXT2,FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2,FPU_ARCH_VFP_V2, NULL),
|
{"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
|
ARM_CPU_OPT ("i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL),
|
/* Maverick */
|
/* Maverick */
|
{"ep9312", ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK), FPU_ARCH_MAVERICK, "ARM920T"},
|
ARM_CPU_OPT ("ep9312", ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
|
{NULL, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL}
|
FPU_ARCH_MAVERICK,
|
|
"ARM920T"),
|
|
{ NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
|
};
|
};
|
|
#undef ARM_CPU_OPT
|
|
|
struct arm_arch_option_table
|
struct arm_arch_option_table
|
{
|
{
|
char *name;
|
char *name;
|
|
size_t name_len;
|
const arm_feature_set value;
|
const arm_feature_set value;
|
const arm_feature_set default_fpu;
|
const arm_feature_set default_fpu;
|
};
|
};
|
|
|
/* This list should, at a minimum, contain all the architecture names
|
/* This list should, at a minimum, contain all the architecture names
|
recognized by GCC. */
|
recognized by GCC. */
|
|
#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF }
|
static const struct arm_arch_option_table arm_archs[] =
|
static const struct arm_arch_option_table arm_archs[] =
|
{
|
{
|
{"all", ARM_ANY, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
|
{"armv1", ARM_ARCH_V1, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
|
{"armv2", ARM_ARCH_V2, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
|
{"armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
|
{"armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
|
{"armv3", ARM_ARCH_V3, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
|
{"armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
|
{"armv4", ARM_ARCH_V4, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
|
{"armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
|
{"armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
|
{"armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA},
|
ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
|
{"armv5", ARM_ARCH_V5, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
|
{"armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
|
{"armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
|
{"armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP),
|
{"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP),
|
{"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP),
|
{"armv6", ARM_ARCH_V6, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP),
|
{"armv6j", ARM_ARCH_V6, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP),
|
{"armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP),
|
{"armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP),
|
{"armv6zk", ARM_ARCH_V6ZK, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6zk", ARM_ARCH_V6ZK, FPU_ARCH_VFP),
|
{"armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP),
|
{"armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP),
|
{"armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP),
|
{"armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP),
|
{"armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
|
{"armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
|
{"armv7", ARM_ARCH_V7, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP),
|
/* The official spelling of the ARMv7 profile variants is the dashed form.
|
/* The official spelling of the ARMv7 profile variants is the dashed form.
|
Accept the non-dashed form for compatibility with old toolchains. */
|
Accept the non-dashed form for compatibility with old toolchains. */
|
{"armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP),
|
{"armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP),
|
{"armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
|
{"armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP),
|
{"armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP),
|
{"armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
|
{"armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP),
|
{"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
|
{"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
|
{"iwmmxt2", ARM_ARCH_IWMMXT2,FPU_ARCH_VFP},
|
ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2,FPU_ARCH_VFP),
|
{NULL, ARM_ARCH_NONE, ARM_ARCH_NONE}
|
{ NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
|
};
|
};
|
|
#undef ARM_ARCH_OPT
|
|
|
/* ISA extensions in the co-processor and main instruction set space. */
|
/* ISA extensions in the co-processor and main instruction set space. */
|
struct arm_option_extension_value_table
|
struct arm_option_extension_value_table
|
{
|
{
|
char *name;
|
char *name;
|
|
size_t name_len;
|
const arm_feature_set value;
|
const arm_feature_set value;
|
const arm_feature_set allowed_archs;
|
const arm_feature_set allowed_archs;
|
};
|
};
|
|
|
/* The following table must be in alphabetical order with a NULL last entry.
|
/* The following table must be in alphabetical order with a NULL last entry.
|
*/
|
*/
|
|
#define ARM_EXT_OPT(N, V, AA) { N, sizeof (N) - 1, V, AA }
|
static const struct arm_option_extension_value_table arm_extensions[] =
|
static const struct arm_option_extension_value_table arm_extensions[] =
|
{
|
{
|
{"idiv", ARM_FEATURE (ARM_EXT_ADIV | ARM_EXT_DIV, 0),
|
ARM_EXT_OPT ("idiv", ARM_FEATURE (ARM_EXT_ADIV | ARM_EXT_DIV, 0),
|
ARM_FEATURE (ARM_EXT_V7A | ARM_EXT_V7R, 0)},
|
ARM_FEATURE (ARM_EXT_V7A | ARM_EXT_V7R, 0)),
|
{"iwmmxt", ARM_FEATURE (0, ARM_CEXT_IWMMXT), ARM_ANY},
|
ARM_EXT_OPT ("iwmmxt",ARM_FEATURE (0, ARM_CEXT_IWMMXT), ARM_ANY),
|
{"iwmmxt2", ARM_FEATURE (0, ARM_CEXT_IWMMXT2), ARM_ANY},
|
ARM_EXT_OPT ("iwmmxt2",
|
{"maverick", ARM_FEATURE (0, ARM_CEXT_MAVERICK), ARM_ANY},
|
ARM_FEATURE (0, ARM_CEXT_IWMMXT2), ARM_ANY),
|
{"mp", ARM_FEATURE (ARM_EXT_MP, 0),
|
ARM_EXT_OPT ("maverick",
|
ARM_FEATURE (ARM_EXT_V7A | ARM_EXT_V7R, 0)},
|
ARM_FEATURE (0, ARM_CEXT_MAVERICK), ARM_ANY),
|
{"os", ARM_FEATURE (ARM_EXT_OS, 0),
|
ARM_EXT_OPT ("mp", ARM_FEATURE (ARM_EXT_MP, 0),
|
ARM_FEATURE (ARM_EXT_V6M, 0)},
|
ARM_FEATURE (ARM_EXT_V7A | ARM_EXT_V7R, 0)),
|
{"sec", ARM_FEATURE (ARM_EXT_SEC, 0),
|
ARM_EXT_OPT ("os", ARM_FEATURE (ARM_EXT_OS, 0),
|
ARM_FEATURE (ARM_EXT_V6K | ARM_EXT_V7A, 0)},
|
ARM_FEATURE (ARM_EXT_V6M, 0)),
|
{"virt", ARM_FEATURE (ARM_EXT_VIRT | ARM_EXT_ADIV | ARM_EXT_DIV, 0),
|
ARM_EXT_OPT ("sec", ARM_FEATURE (ARM_EXT_SEC, 0),
|
ARM_FEATURE (ARM_EXT_V7A, 0)},
|
ARM_FEATURE (ARM_EXT_V6K | ARM_EXT_V7A, 0)),
|
{"xscale", ARM_FEATURE (0, ARM_CEXT_XSCALE), ARM_ANY},
|
ARM_EXT_OPT ("virt", ARM_FEATURE (ARM_EXT_VIRT | ARM_EXT_ADIV
|
{NULL, ARM_ARCH_NONE, ARM_ARCH_NONE}
|
| ARM_EXT_DIV, 0),
|
|
ARM_FEATURE (ARM_EXT_V7A, 0)),
|
|
ARM_EXT_OPT ("xscale",ARM_FEATURE (0, ARM_CEXT_XSCALE), ARM_ANY),
|
|
{ NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
|
};
|
};
|
|
#undef ARM_EXT_OPT
|
|
|
/* ISA floating-point and Advanced SIMD extensions. */
|
/* ISA floating-point and Advanced SIMD extensions. */
|
struct arm_option_fpu_value_table
|
struct arm_option_fpu_value_table
|
{
|
{
|
char *name;
|
char *name;
|
Line 23181... |
Line 23230... |
*opt_p = ext_set;
|
*opt_p = ext_set;
|
|
|
while (str != NULL && *str != 0)
|
while (str != NULL && *str != 0)
|
{
|
{
|
char * ext;
|
char * ext;
|
size_t optlen;
|
size_t len;
|
|
|
if (*str != '+')
|
if (*str != '+')
|
{
|
{
|
as_bad (_("invalid architectural extension"));
|
as_bad (_("invalid architectural extension"));
|
return FALSE;
|
return FALSE;
|
Line 23193... |
Line 23242... |
|
|
str++;
|
str++;
|
ext = strchr (str, '+');
|
ext = strchr (str, '+');
|
|
|
if (ext != NULL)
|
if (ext != NULL)
|
optlen = ext - str;
|
len = ext - str;
|
else
|
else
|
optlen = strlen (str);
|
len = strlen (str);
|
|
|
if (optlen >= 2
|
if (len >= 2 && strncmp (str, "no", 2) == 0)
|
&& strncmp (str, "no", 2) == 0)
|
|
{
|
{
|
if (adding_value != 0)
|
if (adding_value != 0)
|
{
|
{
|
adding_value = 0;
|
adding_value = 0;
|
opt = arm_extensions;
|
opt = arm_extensions;
|
}
|
}
|
|
|
optlen -= 2;
|
len -= 2;
|
str += 2;
|
str += 2;
|
}
|
}
|
else if (optlen > 0)
|
else if (len > 0)
|
{
|
{
|
if (adding_value == -1)
|
if (adding_value == -1)
|
{
|
{
|
adding_value = 1;
|
adding_value = 1;
|
opt = arm_extensions;
|
opt = arm_extensions;
|
Line 23224... |
Line 23272... |
"those to remove"));
|
"those to remove"));
|
return FALSE;
|
return FALSE;
|
}
|
}
|
}
|
}
|
|
|
if (optlen == 0)
|
if (len == 0)
|
{
|
{
|
as_bad (_("missing architectural extension"));
|
as_bad (_("missing architectural extension"));
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
gas_assert (adding_value != -1);
|
gas_assert (adding_value != -1);
|
gas_assert (opt != NULL);
|
gas_assert (opt != NULL);
|
|
|
/* Scan over the options table trying to find an exact match. */
|
/* Scan over the options table trying to find an exact match. */
|
for (; opt->name != NULL; opt++)
|
for (; opt->name != NULL; opt++)
|
if (strncmp (opt->name, str, optlen) == 0
|
if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
|
&& strlen (opt->name) == optlen)
|
|
{
|
{
|
/* Check we can apply the extension to this architecture. */
|
/* Check we can apply the extension to this architecture. */
|
if (!ARM_CPU_HAS_FEATURE (*ext_set, opt->allowed_archs))
|
if (!ARM_CPU_HAS_FEATURE (*ext_set, opt->allowed_archs))
|
{
|
{
|
as_bad (_("extension does not apply to the base architecture"));
|
as_bad (_("extension does not apply to the base architecture"));
|
Line 23260... |
Line 23307... |
{
|
{
|
/* Did we fail to find an extension because it wasn't specified in
|
/* Did we fail to find an extension because it wasn't specified in
|
alphabetical order, or because it does not exist? */
|
alphabetical order, or because it does not exist? */
|
|
|
for (opt = arm_extensions; opt->name != NULL; opt++)
|
for (opt = arm_extensions; opt->name != NULL; opt++)
|
if (strncmp (opt->name, str, optlen) == 0)
|
if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
|
break;
|
break;
|
|
|
if (opt->name == NULL)
|
if (opt->name == NULL)
|
as_bad (_("unknown architectural extension `%s'"), str);
|
as_bad (_("unknown architectural extension `%s'"), str);
|
else
|
else
|
Line 23289... |
Line 23336... |
static bfd_boolean
|
static bfd_boolean
|
arm_parse_cpu (char * str)
|
arm_parse_cpu (char * str)
|
{
|
{
|
const struct arm_cpu_option_table * opt;
|
const struct arm_cpu_option_table * opt;
|
char * ext = strchr (str, '+');
|
char * ext = strchr (str, '+');
|
int optlen;
|
size_t len;
|
|
|
if (ext != NULL)
|
if (ext != NULL)
|
optlen = ext - str;
|
len = ext - str;
|
else
|
else
|
optlen = strlen (str);
|
len = strlen (str);
|
|
|
if (optlen == 0)
|
if (len == 0)
|
{
|
{
|
as_bad (_("missing cpu name `%s'"), str);
|
as_bad (_("missing cpu name `%s'"), str);
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
for (opt = arm_cpus; opt->name != NULL; opt++)
|
for (opt = arm_cpus; opt->name != NULL; opt++)
|
if (strncmp (opt->name, str, optlen) == 0)
|
if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
|
{
|
{
|
mcpu_cpu_opt = &opt->value;
|
mcpu_cpu_opt = &opt->value;
|
mcpu_fpu_opt = &opt->default_fpu;
|
mcpu_fpu_opt = &opt->default_fpu;
|
if (opt->canonical_name)
|
if (opt->canonical_name)
|
strcpy (selected_cpu_name, opt->canonical_name);
|
strcpy (selected_cpu_name, opt->canonical_name);
|
else
|
else
|
{
|
{
|
int i;
|
size_t i;
|
|
|
for (i = 0; i < optlen; i++)
|
for (i = 0; i < len; i++)
|
selected_cpu_name[i] = TOUPPER (opt->name[i]);
|
selected_cpu_name[i] = TOUPPER (opt->name[i]);
|
selected_cpu_name[i] = 0;
|
selected_cpu_name[i] = 0;
|
}
|
}
|
|
|
if (ext != NULL)
|
if (ext != NULL)
|
Line 23333... |
Line 23380... |
static bfd_boolean
|
static bfd_boolean
|
arm_parse_arch (char * str)
|
arm_parse_arch (char * str)
|
{
|
{
|
const struct arm_arch_option_table *opt;
|
const struct arm_arch_option_table *opt;
|
char *ext = strchr (str, '+');
|
char *ext = strchr (str, '+');
|
int optlen;
|
size_t len;
|
|
|
if (ext != NULL)
|
if (ext != NULL)
|
optlen = ext - str;
|
len = ext - str;
|
else
|
else
|
optlen = strlen (str);
|
len = strlen (str);
|
|
|
if (optlen == 0)
|
if (len == 0)
|
{
|
{
|
as_bad (_("missing architecture name `%s'"), str);
|
as_bad (_("missing architecture name `%s'"), str);
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
for (opt = arm_archs; opt->name != NULL; opt++)
|
for (opt = arm_archs; opt->name != NULL; opt++)
|
if (strncmp (opt->name, str, optlen) == 0)
|
if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
|
{
|
{
|
march_cpu_opt = &opt->value;
|
march_cpu_opt = &opt->value;
|
march_fpu_opt = &opt->default_fpu;
|
march_fpu_opt = &opt->default_fpu;
|
strcpy (selected_cpu_name, opt->name);
|
strcpy (selected_cpu_name, opt->name);
|
|
|
Line 23639... |
Line 23686... |
/* Choose the architecture based on the capabilities of the requested cpu
|
/* Choose the architecture based on the capabilities of the requested cpu
|
(if any) and/or the instructions actually used. */
|
(if any) and/or the instructions actually used. */
|
ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
|
ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
|
ARM_MERGE_FEATURE_SETS (flags, flags, *mfpu_opt);
|
ARM_MERGE_FEATURE_SETS (flags, flags, *mfpu_opt);
|
ARM_MERGE_FEATURE_SETS (flags, flags, selected_cpu);
|
ARM_MERGE_FEATURE_SETS (flags, flags, selected_cpu);
|
|
|
|
if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
|
|
ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
|
|
|
|
if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
|
|
ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
|
|
|
/*Allow the user to override the reported architecture. */
|
/*Allow the user to override the reported architecture. */
|
if (object_arch)
|
if (object_arch)
|
{
|
{
|
ARM_CLEAR_FEATURE (flags, flags, arm_arch_any);
|
ARM_CLEAR_FEATURE (flags, flags, arm_arch_any);
|
ARM_MERGE_FEATURE_SETS (flags, flags, *object_arch);
|
ARM_MERGE_FEATURE_SETS (flags, flags, *object_arch);
|
Line 23813... |
Line 23867... |
else
|
else
|
{
|
{
|
int i;
|
int i;
|
for (i = 0; opt->name[i]; i++)
|
for (i = 0; opt->name[i]; i++)
|
selected_cpu_name[i] = TOUPPER (opt->name[i]);
|
selected_cpu_name[i] = TOUPPER (opt->name[i]);
|
|
|
selected_cpu_name[i] = 0;
|
selected_cpu_name[i] = 0;
|
}
|
}
|
ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt);
|
ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt);
|
*input_line_pointer = saved_char;
|
*input_line_pointer = saved_char;
|
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|