aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog44
-rw-r--r--gas/NEWS2
-rw-r--r--gas/config/tc-ppc.c549
-rw-r--r--gas/config/tc-ppc.h7
-rw-r--r--gas/testsuite/ChangeLog22
-rw-r--r--gas/testsuite/gas/ppc/ppc.exp8
-rw-r--r--gas/testsuite/gas/ppc/vle-reloc.d172
-rw-r--r--gas/testsuite/gas/ppc/vle-reloc.s95
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-1.d39
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-1.s34
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-2.d83
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-2.s78
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-3.d24
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-3.s18
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-4.d23
-rwxr-xr-xgas/testsuite/gas/ppc/vle-simple-4.s19
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-5.d20
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-5.s13
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-6.d60
-rw-r--r--gas/testsuite/gas/ppc/vle-simple-6.s59
-rwxr-xr-xgas/testsuite/gas/ppc/vle.d150
-rwxr-xr-xgas/testsuite/gas/ppc/vle.s184
22 files changed, 1610 insertions, 93 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 82bfc0ec..178dca7 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,47 @@
+2012-05-14 James Lemke <jwlemke@codesourcery.com>
+
+ * config/tc-ppc.c (insn_validate): New func of existing code to call..
+ (ppc_setup_opcodes): ..from 2 places here.
+ Revise for second (VLE) opcode table.
+ Add #ifdef'd code to print opcode tables.
+
+2012-05-14 James Lemke <jwlemke@codesourcery.com>
+
+ * config/tc-ppc.c (ppc_setup_opcodes): Allow out-of-order
+ for the VLE conditional branches.
+
+2012-05-14 Catherine Moore <clm@codesourcery.com>
+ Maciej W. Rozycki <macro@codesourcery.com>
+ Rhonda Wittels <rhonda@codesourcery.com>
+
+ * config/tc-ppc.c (PPC_VLE_SPLIT16A): New macro.
+ (PPC_VLE_SPLIT16D): New macro.
+ (PPC_VLE_LO16A): New macro.
+ (PPC_VLE_LO16D): New macro.
+ (PPC_VLE_HI16A): New macro.
+ (PPC_VLE_HI16D): New macro.
+ (PPC_VLE_HA16A): New macro.
+ (PPC_VLE_HA16D): New macro.
+ (PPC_APUINFO_VLE): New definition.
+ (md_chars_to_number): New function.
+ (md_parse_option): Check for combinations of little
+ endian and -mvle.
+ (md_show_usage): Document -mvle.
+ (ppc_arch): Recognize VLE.
+ (ppc_mach): Recognize bfd_mach_ppc_vle.
+ (ppc_setup_opcodes): Print the opcode table if
+ * config/tc-ppc.h (ppc_frag_check): Declare.
+ * doc/c-ppc.texi: Document -mvle.
+ * NEWS: Mention PowerPC VLE port.
+
+2012-05-14 Catherine Moore <clm@codesourcery.com>
+
+ * config/tc-ppc.h (ppc_dw2_line_min_insn_length): Declare.
+ (DWARF2_LINE_MIN_INSN_LENGTH): Redefine.
+ * config/tc-ppc.c (ppc_dw2_line_min_insn_length): New.
+ * dwarf2dbg.c (scale_addr_delta): Handle values of 1
+ for DWARF2_LINE_MIN_INSN_LENGTH.
+
2012-05-12 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (tc_gen_reloc): Remove x32 addend overflow
diff --git a/gas/NEWS b/gas/NEWS
index e8dcf50..08e6384 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
-*- text -*-
+* Add support for the VLE extension to the PowerPC architecture.
+
* Add support for the Freescale XGATE architecture.
* Add support for .bundle_align_mode, .bundle_lock, and .bundle_unlock
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 0e7f017..f146169 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -64,14 +64,40 @@ static int set_target_endian = 0;
/* #lo(value) denotes the least significant 16 bits of the indicated. */
#define PPC_LO(v) ((v) & 0xffff)
+/* Split the indicated value with the msbs in bits 11-15
+ and the lsbs in bits 21-31. */
+#define PPC_VLE_SPLIT16A(v) ((v & 0xf800) << 11) | (v & 0x7ff)
+
+/* Split the indicated value with the msbs in bits 6-10
+ and the lsbs in bits 21-31. */
+#define PPC_VLE_SPLIT16D(v) ((v & 0xf800) << 5) | (v & 0x7ff)
+
+/* #lo(value) denotes the lsb 16 bits in split16a format. */
+#define PPC_VLE_LO16A(v) PPC_VLE_SPLIT16A(PPC_LO(v))
+
+/* #lo(value) denotes the lsb 16 bits in split16d format. */
+#define PPC_VLE_LO16D(v) PPC_VLE_SPLIT16D(PPC_LO(v))
+
/* #hi(value) denotes bits 16 through 31 of the indicated value. */
#define PPC_HI(v) (((v) >> 16) & 0xffff)
+/* #lo(value) denotes the msb 16 bits in split16a format. */
+#define PPC_VLE_HI16A(v) PPC_VLE_SPLIT16A(PPC_HI(v))
+
+/* #lo(value) denotes the msb 16 bits in split16d format. */
+#define PPC_VLE_HI16D(v) PPC_VLE_SPLIT16D(PPC_HI(v))
+
/* #ha(value) denotes the high adjusted value: bits 16 through 31 of
the indicated value, compensating for #lo() being treated as a
signed number. */
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
+/* #ha(value) denotes the high adjusted value in split16a format. */
+#define PPC_VLE_HA16A(v) PPC_VLE_SPLIT16A(PPC_HA(v))
+
+/* #ha(value) denotes the high adjusted value in split16d format. */
+#define PPC_VLE_HA16D(v) PPC_VLE_SPLIT16D(PPC_HA(v))
+
/* #higher(value) denotes bits 32 through 47 of the indicated value. */
#define PPC_HIGHER(v) (((v) >> 16 >> 16) & 0xffff)
@@ -1038,6 +1064,7 @@ symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE" */
#define PPC_APUINFO_SPE 0x100
#define PPC_APUINFO_EFS 0x101
#define PPC_APUINFO_BRLOCK 0x102
+#define PPC_APUINFO_VLE 0x104
/*
* We keep a list of APUinfo
@@ -1059,6 +1086,35 @@ const struct option md_longopts[] = {
};
const size_t md_longopts_size = sizeof (md_longopts);
+/* Convert the target integer stored in N bytes in BUF to a host
+ integer, returning that value. */
+
+static valueT
+md_chars_to_number (char *buf, int n)
+{
+ valueT result = 0;
+ unsigned char *p = (unsigned char *) buf;
+
+ if (target_big_endian)
+ {
+ while (n--)
+ {
+ result <<= 8;
+ result |= (*p++ & 0xff);
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ result <<= 8;
+ result |= (p[n] & 0xff);
+ }
+ }
+
+ return result;
+}
+
int
md_parse_option (int c, char *arg)
{
@@ -1079,6 +1135,8 @@ md_parse_option (int c, char *arg)
{
target_big_endian = 0;
set_target_endian = 1;
+ if (ppc_cpu & PPC_OPCODE_VLE)
+ as_bad (_("The use of -mvle requires big endian."));
}
else
return 0;
@@ -1126,8 +1184,13 @@ md_parse_option (int c, char *arg)
break;
case 'm':
- if ((new_cpu = ppc_parse_cpu (ppc_cpu, arg)) != 0)
- ppc_cpu = new_cpu;
+ new_cpu = ppc_parse_cpu (ppc_cpu, arg);
+ if (new_cpu != 0)
+ {
+ ppc_cpu = new_cpu;
+ if (set_target_endian && target_big_endian == 0)
+ as_bad (_("The use of -mvle requires big endian."));
+ }
else if (strcmp (arg, "regnames") == 0)
reg_names_p = TRUE;
@@ -1160,6 +1223,8 @@ md_parse_option (int c, char *arg)
{
target_big_endian = 0;
set_target_endian = 1;
+ if (ppc_cpu & PPC_OPCODE_VLE)
+ as_bad (_("The use of -mvle requires big endian."));
}
else if (strcmp (arg, "big") == 0 || strcmp (arg, "big-endian") == 0)
@@ -1268,6 +1333,7 @@ PowerPC options:\n\
-me5500, generate code for Freescale e5500 core complex\n\
-me6500, generate code for Freescale e6500 core complex\n\
-mspe generate code for Motorola SPE instructions\n\
+-mvle generate code for Freescale VLE instructions\n\
-mtitan generate code for AppliedMicro Titan core complex\n\
-mregnames Allow symbolic names for registers\n\
-mno-regnames Do not allow symbolic names for registers\n"));
@@ -1328,9 +1394,11 @@ ppc_arch (void)
if ((ppc_cpu & PPC_OPCODE_PPC) != 0)
return bfd_arch_powerpc;
- else if ((ppc_cpu & PPC_OPCODE_POWER) != 0)
+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
+ return bfd_arch_powerpc;
+ if ((ppc_cpu & PPC_OPCODE_POWER) != 0)
return bfd_arch_rs6000;
- else if ((ppc_cpu & (PPC_OPCODE_COMMON | PPC_OPCODE_ANY)) != 0)
+ if ((ppc_cpu & (PPC_OPCODE_COMMON | PPC_OPCODE_ANY)) != 0)
{
if (strcmp (default_cpu, "rs6000") == 0)
return bfd_arch_rs6000;
@@ -1351,6 +1419,8 @@ ppc_mach (void)
return bfd_mach_rs6k;
else if (ppc_cpu & PPC_OPCODE_TITAN)
return bfd_mach_ppc_titan;
+ else if (ppc_cpu & PPC_OPCODE_VLE)
+ return bfd_mach_ppc_vle;
else
return bfd_mach_ppc;
}
@@ -1384,6 +1454,54 @@ ppc_target_format (void)
#endif
}
+/* Validate one entry in powerpc_opcodes[] or vle_opcodes[].
+ Return TRUE if there's a problem, otherwise FALSE. */
+
+static bfd_boolean
+insn_validate (const struct powerpc_opcode *op)
+{
+ const unsigned char *o;
+ unsigned long omask = op->mask;
+
+ /* The mask had better not trim off opcode bits. */
+ if ((op->opcode & omask) != op->opcode)
+ {
+ as_bad (_("mask trims opcode bits for %s"), op->name);
+ return TRUE;
+ }
+
+ /* The operands must not overlap the opcode or each other. */
+ for (o = op->operands; *o; ++o)
+ {
+ if (*o >= num_powerpc_operands)
+ {
+ as_bad (_("operand index error for %s"), op->name);
+ return TRUE;
+ }
+ else
+ {
+ const struct powerpc_operand *operand = &powerpc_operands[*o];
+ if (operand->shift != PPC_OPSHIFT_INV)
+ {
+ unsigned long mask;
+
+ if (operand->shift >= 0)
+ mask = operand->bitm << operand->shift;
+ else
+ mask = operand->bitm >> -operand->shift;
+ if (omask & mask)
+ {
+ as_bad (_("operand %d overlap in %s"),
+ (int) (o - op->operands), op->name);
+ return TRUE;
+ }
+ omask |= mask;
+ }
+ }
+ }
+ return FALSE;
+}
+
/* Insert opcodes and macros into hash tables. Called at startup and
for .cpu pseudo. */
@@ -1440,89 +1558,82 @@ ppc_setup_opcodes (void)
{
if (ENABLE_CHECKING)
{
- const unsigned char *o;
- unsigned long omask = op->mask;
-
if (op != powerpc_opcodes)
{
+ int old_opcode = PPC_OP (op[-1].opcode);
+ int new_opcode = PPC_OP (op[0].opcode);
+
+#ifdef PRINT_OPCODE_TABLE
+ printf ("%-14s\t#%04d\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+ op->name, op - powerpc_opcodes, (unsigned int) new_opcode,
+ (unsigned int) op->opcode, (unsigned int) op->mask,
+ (unsigned long long) op->flags);
+#endif
+
/* The major opcodes had better be sorted. Code in the
disassembler assumes the insns are sorted according to
major opcode. */
- if (PPC_OP (op[0].opcode) < PPC_OP (op[-1].opcode))
+ if (new_opcode < old_opcode)
{
as_bad (_("major opcode is not sorted for %s"),
op->name);
bad_insn = TRUE;
}
-
- /* Warn if the table isn't more strictly ordered.
- Unfortunately it doesn't seem possible to order the
- table on much more than the major opcode, which makes
- it difficult to implement a binary search in the
- disassembler. The problem is that we have multiple
- ways to disassemble instructions, and we usually want
- to choose a more specific form (with more bits set in
- the opcode) than a more general form. eg. all of the
- following are equivalent:
- bne label # opcode = 0x40820000, mask = 0xff830003
- bf 2,label # opcode = 0x40800000, mask = 0xff800003
- bc 4,2,label # opcode = 0x40000000, mask = 0xfc000003
-
- There are also cases where the table needs to be out
- of order to disassemble the correct instruction for
- processor variants. */
- else if (0)
- {
- unsigned long t1 = op[0].opcode;
- unsigned long t2 = op[-1].opcode;
-
- if (((t1 ^ t2) & 0xfc0007ff) == 0
- && (t1 & 0xfc0006df) == 0x7c000286)
- {
- /* spr field is split. */
- t1 = ((t1 & ~0x1ff800)
- | ((t1 & 0xf800) << 5) | ((t1 & 0x1f0000) >> 5));
- t2 = ((t2 & ~0x1ff800)
- | ((t2 & 0xf800) << 5) | ((t2 & 0x1f0000) >> 5));
- }
- if (t1 < t2)
- as_warn (_("%s (%08lx %08lx) after %s (%08lx %08lx)"),
- op[0].name, op[0].opcode, op[0].mask,
- op[-1].name, op[-1].opcode, op[-1].mask);
- }
}
+ bad_insn |= insn_validate (op);
+ }
+
+ if ((ppc_cpu & op->flags) != 0
+ && !(ppc_cpu & op->deprecated))
+ {
+ const char *retval;
- /* The mask had better not trim off opcode bits. */
- if ((op->opcode & omask) != op->opcode)
+ retval = hash_insert (ppc_hash, op->name, (void *) op);
+ if (retval != NULL)
{
- as_bad (_("mask trims opcode bits for %s"),
+ as_bad (_("duplicate instruction %s"),
op->name);
bad_insn = TRUE;
}
+ }
+ }
- /* The operands must not overlap the opcode or each other. */
- for (o = op->operands; *o; ++o)
- if (*o >= num_powerpc_operands)
- {
- as_bad (_("operand index error for %s"),
- op->name);
- bad_insn = TRUE;
- }
- else
- {
- const struct powerpc_operand *operand = &powerpc_operands[*o];
- if (operand->shift >= 0)
- {
- unsigned long mask = operand->bitm << operand->shift;
- if (omask & mask)
- {
- as_bad (_("operand %d overlap in %s"),
- (int) (o - op->operands), op->name);
- bad_insn = TRUE;
- }
- omask |= mask;
- }
- }
+ if ((ppc_cpu & PPC_OPCODE_ANY) != 0)
+ for (op = powerpc_opcodes; op < op_end; op++)
+ hash_insert (ppc_hash, op->name, (void *) op);
+
+ op_end = vle_opcodes + vle_num_opcodes;
+ for (op = vle_opcodes; op < op_end; op++)
+ {
+ if (ENABLE_CHECKING)
+ {
+ if (op != vle_opcodes)
+ {
+ unsigned old_seg, new_seg;
+
+ old_seg = VLE_OP (op[-1].opcode, op[-1].mask);
+ old_seg = VLE_OP_TO_SEG (old_seg);
+ new_seg = VLE_OP (op[0].opcode, op[0].mask);
+ new_seg = VLE_OP_TO_SEG (new_seg);
+
+#ifdef PRINT_OPCODE_TABLE
+ printf ("%-14s\t#%04d\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+ op->name, op - powerpc_opcodes, (unsigned int) new_opcode,
+ (unsigned int) op->opcode, (unsigned int) op->mask,
+ (unsigned long long) op->flags);
+#endif
+ /* The major opcodes had better be sorted. Code in the
+ disassembler assumes the insns are sorted according to
+ major opcode. */
+ if (new_seg < old_seg)
+ {
+ as_bad (_("major opcode is not sorted for %s"),
+ op->name);
+ bad_insn = TRUE;
+ }
+ }
+
+ bad_insn |= insn_validate (op);
}
if ((ppc_cpu & op->flags) != 0
@@ -1540,8 +1651,8 @@ ppc_setup_opcodes (void)
}
}
- if ((ppc_cpu & PPC_OPCODE_ANY) != 0)
- for (op = powerpc_opcodes; op < op_end; op++)
+ if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
+ for (op = vle_opcodes; op < op_end; op++)
hash_insert (ppc_hash, op->name, (void *) op);
/* Insert the macros into a hash table. */
@@ -1743,8 +1854,10 @@ ppc_insert_operand (unsigned long insn,
if (errmsg != (const char *) NULL)
as_bad_where (file, line, "%s", errmsg);
}
- else
+ else if (operand->shift >= 0)
insn |= ((long) val & operand->bitm) << operand->shift;
+ else
+ insn |= ((long) val & operand->bitm) >> -operand->shift;
return insn;
}
@@ -1826,6 +1939,9 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
MAP32 ("local", BFD_RELOC_PPC_LOCAL24PC),
MAP32 ("pltrel", BFD_RELOC_32_PLT_PCREL),
MAP32 ("sdarel", BFD_RELOC_GPREL16),
+ MAP32 ("sdarel@l", BFD_RELOC_PPC_VLE_SDAREL_LO16A),
+ MAP32 ("sdarel@h", BFD_RELOC_PPC_VLE_SDAREL_HI16A),
+ MAP32 ("sdarel@ha", BFD_RELOC_PPC_VLE_SDAREL_HA16A),
MAP32 ("naddr", BFD_RELOC_PPC_EMB_NADDR32),
MAP32 ("naddr16", BFD_RELOC_PPC_EMB_NADDR16),
MAP32 ("naddr@l", BFD_RELOC_PPC_EMB_NADDR16_LO),
@@ -1835,6 +1951,7 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
MAP32 ("sda2rel", BFD_RELOC_PPC_EMB_SDA2REL),
MAP32 ("sda2i16", BFD_RELOC_PPC_EMB_SDA2I16),
MAP32 ("sda21", BFD_RELOC_PPC_EMB_SDA21),
+ MAP32 ("sda21@l", BFD_RELOC_PPC_VLE_SDA21_LO),
MAP32 ("mrkref", BFD_RELOC_PPC_EMB_MRKREF),
MAP32 ("relsect", BFD_RELOC_PPC_EMB_RELSEC16),
MAP32 ("relsect@l", BFD_RELOC_PPC_EMB_RELST_LO),
@@ -2371,6 +2488,22 @@ struct ppc_fixup
#define MAX_INSN_FIXUPS (5)
+/* Form I16L. */
+#define E_OR2I_INSN 0x7000C000
+#define E_AND2I_DOT_INSN 0x7000C800
+#define E_OR2IS_INSN 0x7000D000
+#define E_LIS_INSN 0x7000E000
+#define E_AND2IS_DOT_INSN 0x7000E800
+
+/* Form I16A. */
+#define E_ADD2I_DOT_INSN 0x70008800
+#define E_ADD2IS_INSN 0x70009000
+#define E_CMP16I_INSN 0x70009800
+#define E_MULL2I_INSN 0x7000A000
+#define E_CMPL16I_INSN 0x7000A800
+#define E_CMPH16I_INSN 0x7000B000
+#define E_CMPHL16I_INSN 0x7000B800
+
/* This routine is called for each instruction to be assembled. */
void
@@ -2388,6 +2521,7 @@ md_assemble (char *str)
char *f;
int addr_mod;
int i;
+ unsigned int insn_length;
#ifdef OBJ_ELF
bfd_reloc_code_real_type reloc;
#endif
@@ -2637,12 +2771,15 @@ md_assemble (char *str)
else
#endif /* TE_PE */
{
- if ((reg_names_p && (operand->flags & PPC_OPERAND_CR) != 0)
+ if ((reg_names_p
+ && (((operand->flags & PPC_OPERAND_CR_BIT) != 0)
+ || ((operand->flags & PPC_OPERAND_CR_REG) != 0)))
|| !register_name (&ex))
{
char save_lex = lex_type['%'];
- if ((operand->flags & PPC_OPERAND_CR) != 0)
+ if (((operand->flags & PPC_OPERAND_CR_REG) != 0)
+ || (operand->flags & PPC_OPERAND_CR_BIT) != 0)
{
cr_operand = TRUE;
lex_type['%'] |= LEX_BEGIN_NAME;
@@ -2810,6 +2947,73 @@ md_assemble (char *str)
break;
}
+ /* If VLE-mode convert LO/HI/HA relocations. */
+ if (opcode->flags & PPC_OPCODE_VLE)
+ {
+ int tmp_insn = insn & opcode->mask;
+
+ int use_d_reloc = (tmp_insn == E_OR2I_INSN
+ || tmp_insn == E_AND2I_DOT_INSN
+ || tmp_insn == E_OR2IS_INSN
+ || tmp_insn == E_LIS_INSN
+ || tmp_insn == E_AND2IS_DOT_INSN);
+
+
+ int use_a_reloc = (tmp_insn == E_ADD2I_DOT_INSN
+ || tmp_insn == E_ADD2IS_INSN
+ || tmp_insn == E_CMP16I_INSN
+ || tmp_insn == E_MULL2I_INSN
+ || tmp_insn == E_CMPL16I_INSN
+ || tmp_insn == E_CMPH16I_INSN
+ || tmp_insn == E_CMPHL16I_INSN);
+
+ switch (reloc)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_PPC_EMB_SDA21:
+ reloc = BFD_RELOC_PPC_VLE_SDA21;
+ break;
+
+ case BFD_RELOC_LO16:
+ if (use_d_reloc)
+ reloc = BFD_RELOC_PPC_VLE_LO16D;
+ else if (use_a_reloc)
+ reloc = BFD_RELOC_PPC_VLE_LO16A;
+ break;
+
+ case BFD_RELOC_HI16:
+ if (use_d_reloc)
+ reloc = BFD_RELOC_PPC_VLE_HI16D;
+ else if (use_a_reloc)
+ reloc = BFD_RELOC_PPC_VLE_HI16A;
+ break;
+
+ case BFD_RELOC_HI16_S:
+ if (use_d_reloc)
+ reloc = BFD_RELOC_PPC_VLE_HA16D;
+ else if (use_a_reloc)
+ reloc = BFD_RELOC_PPC_VLE_HA16A;
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDAREL_LO16A:
+ if (use_d_reloc)
+ reloc = BFD_RELOC_PPC_VLE_SDAREL_LO16D;
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDAREL_HI16A:
+ if (use_d_reloc)
+ reloc = BFD_RELOC_PPC_VLE_SDAREL_HI16D;
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDAREL_HA16A:
+ if (use_d_reloc)
+ reloc = BFD_RELOC_PPC_VLE_SDAREL_HA16D;
+ break;
+ }
+ }
+
/* For the absolute forms of branches, convert the PC
relative form back into the absolute. */
if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
@@ -2974,8 +3178,8 @@ md_assemble (char *str)
as_bad (_("junk at end of line: `%s'"), str);
#ifdef OBJ_ELF
- /* Do we need/want a APUinfo section? */
- if ((ppc_cpu & (PPC_OPCODE_E500 | PPC_OPCODE_E500MC)) != 0)
+ /* Do we need/want an APUinfo section? */
+ if ((ppc_cpu & (PPC_OPCODE_E500 | PPC_OPCODE_E500MC | PPC_OPCODE_VLE)) != 0)
{
/* These are all version "1". */
if (opcode->flags & PPC_OPCODE_SPE)
@@ -2992,20 +3196,41 @@ md_assemble (char *str)
ppc_apuinfo_section_add (PPC_APUINFO_CACHELCK, 1);
if (opcode->flags & PPC_OPCODE_RFMCI)
ppc_apuinfo_section_add (PPC_APUINFO_RFMCI, 1);
+ if (opcode->flags & PPC_OPCODE_VLE)
+ ppc_apuinfo_section_add (PPC_APUINFO_VLE, 1);
}
#endif
/* Write out the instruction. */
- f = frag_more (4);
- addr_mod = frag_now_fix () & 3;
+ /* Differentiate between two and four byte insns. */
+ if (ppc_mach () == bfd_mach_ppc_vle)
+ {
+ if (PPC_OP_SE_VLE (insn))
+ insn_length = 2;
+ else
+ insn_length = 4;
+ addr_mod = frag_now_fix () & 1;
+ }
+ else
+ {
+ insn_length = 4;
+ addr_mod = frag_now_fix () & 3;
+ }
+ /* All instructions can start on a 2 byte boundary for VLE. */
+ f = frag_more (insn_length);
if (frag_now->has_code && frag_now->insn_addr != addr_mod)
- as_bad (_("instruction address is not a multiple of 4"));
+ {
+ if (ppc_mach() == bfd_mach_ppc_vle)
+ as_bad (_("instruction address is not a multiple of 2"));
+ else
+ as_bad (_("instruction address is not a multiple of 4"));
+ }
frag_now->insn_addr = addr_mod;
frag_now->has_code = 1;
- md_number_to_chars (f, insn, 4);
+ md_number_to_chars (f, insn, insn_length);
#ifdef OBJ_ELF
- dwarf2_emit_insn (4);
+ dwarf2_emit_insn (insn_length);
#endif
/* Create any fixups. At this point we do not use a
@@ -3049,6 +3274,12 @@ md_assemble (char *str)
case BFD_RELOC_LO16:
case BFD_RELOC_HI16:
case BFD_RELOC_HI16_S:
+ case BFD_RELOC_PPC_VLE_LO16A:
+ case BFD_RELOC_PPC_VLE_LO16D:
+ case BFD_RELOC_PPC_VLE_HI16A:
+ case BFD_RELOC_PPC_VLE_HI16D:
+ case BFD_RELOC_PPC_VLE_HA16A:
+ case BFD_RELOC_PPC_VLE_HA16D:
#ifdef OBJ_ELF
case BFD_RELOC_PPC64_HIGHER:
case BFD_RELOC_PPC64_HIGHER_S:
@@ -3068,7 +3299,7 @@ md_assemble (char *str)
operand = &powerpc_operands[fixups[i].opindex];
fix_new_exp (frag_now,
f - frag_now->fr_literal,
- 4,
+ insn_length,
&fixups[i].exp,
(operand->flags & PPC_OPERAND_RELATIVE) != 0,
((bfd_reloc_code_real_type)
@@ -5953,6 +6184,24 @@ ppc_fix_adjustable (fixS *fix)
}
#endif
+void
+ppc_frag_check (struct frag *fragP)
+{
+ if (!fragP->has_code)
+ return;
+
+ if (ppc_mach() == bfd_mach_ppc_vle)
+ {
+ if (((fragP->fr_address + fragP->insn_addr) & 1) != 0)
+ as_bad (_("instruction address is not a multiple of 2"));
+ }
+ else
+ {
+ if (((fragP->fr_address + fragP->insn_addr) & 3) != 0)
+ as_bad (_("instruction address is not a multiple of 4"));
+ }
+}
+
/* Implement HANDLE_ALIGN. This writes the NOP pattern into an
rs_align_code frag. */
@@ -5962,7 +6211,14 @@ ppc_handle_align (struct frag *fragP)
valueT count = (fragP->fr_next->fr_address
- (fragP->fr_address + fragP->fr_fix));
- if (count != 0 && (count & 3) == 0)
+ if (ppc_mach() == bfd_mach_ppc_vle && count != 0 && (count & 1) == 0)
+ {
+ char *dest = fragP->fr_literal + fragP->fr_fix;
+
+ fragP->fr_var = 2;
+ md_number_to_chars (dest, 0x4400, 2);
+ }
+ else if (count != 0 && (count & 3) == 0)
{
char *dest = fragP->fr_literal + fragP->fr_fix;
@@ -6117,16 +6373,36 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
value, and stuff the instruction back again. */
where = fixP->fx_frag->fr_literal + fixP->fx_where;
if (target_big_endian)
- insn = bfd_getb32 ((unsigned char *) where);
+ {
+ if (fixP->fx_size == 4)
+ insn = bfd_getb32 ((unsigned char *) where);
+ else
+ insn = bfd_getb16 ((unsigned char *) where);
+ }
else
- insn = bfd_getl32 ((unsigned char *) where);
+ {
+ if (fixP->fx_size == 4)
+ insn = bfd_getl32 ((unsigned char *) where);
+ else
+ insn = bfd_getl16 ((unsigned char *) where);
+ }
insn = ppc_insert_operand (insn, operand, (offsetT) value,
fixP->tc_fix_data.ppc_cpu,
fixP->fx_file, fixP->fx_line);
if (target_big_endian)
- bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ {
+ if (fixP->fx_size == 4)
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ else
+ bfd_putb16 ((bfd_vma) insn, (unsigned char *) where);
+ }
else
- bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+ {
+ if (fixP->fx_size == 4)
+ bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+ else
+ bfd_putl16 ((bfd_vma) insn, (unsigned char *) where);
+ }
if (fixP->fx_done)
/* Nothing else to do here. */
@@ -6152,6 +6428,18 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
fixP->fx_where += 2;
#endif
}
+ else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+ && operand->bitm == 0x1fe
+ && operand->shift == -1)
+ fixP->fx_r_type = BFD_RELOC_PPC_VLE_REL8;
+ else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+ && operand->bitm == 0xfffe
+ && operand->shift == 0)
+ fixP->fx_r_type = BFD_RELOC_PPC_VLE_REL15;
+ else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+ && operand->bitm == 0x1fffffe
+ && operand->shift == 0)
+ fixP->fx_r_type = BFD_RELOC_PPC_VLE_REL24;
else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
&& operand->bitm == 0x3fffffc
&& operand->shift == 0)
@@ -6336,6 +6624,91 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
PPC_HA (value), 2);
break;
+ case BFD_RELOC_PPC_VLE_SDAREL_LO16A:
+ case BFD_RELOC_PPC_VLE_LO16A:
+ {
+ int tval = PPC_VLE_LO16A (value);
+ valueT oldval = md_chars_to_number (
+ fixP->fx_frag->fr_literal + fixP->fx_where, 4);
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ (oldval | tval), 4);
+ }
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDAREL_LO16D:
+ case BFD_RELOC_PPC_VLE_LO16D:
+ {
+ int tval = PPC_VLE_LO16D (value);
+ valueT oldval = md_chars_to_number (
+ fixP->fx_frag->fr_literal + fixP->fx_where, 4);
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ (oldval | tval), 4);
+ }
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDAREL_HI16A:
+ case BFD_RELOC_PPC_VLE_HI16A:
+ {
+ int tval = PPC_VLE_HI16A (value);
+ valueT oldval = md_chars_to_number (
+ fixP->fx_frag->fr_literal + fixP->fx_where, 4);
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ (oldval | tval), 4);
+ }
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDAREL_HI16D:
+ case BFD_RELOC_PPC_VLE_HI16D:
+ {
+ int tval = PPC_VLE_HI16D (value);
+ valueT oldval = md_chars_to_number (
+ fixP->fx_frag->fr_literal + fixP->fx_where, 4);
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ (oldval | tval), 4);
+ }
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDAREL_HA16A:
+ case BFD_RELOC_PPC_VLE_HA16A:
+ {
+ int tval = PPC_VLE_HA16A (value);
+ valueT oldval = md_chars_to_number (
+ fixP->fx_frag->fr_literal + fixP->fx_where, 4);
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ (oldval | tval), 4);
+ }
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDAREL_HA16D:
+ case BFD_RELOC_PPC_VLE_HA16D:
+ {
+ int tval = PPC_VLE_HA16D (value);
+ valueT oldval = md_chars_to_number (
+ fixP->fx_frag->fr_literal + fixP->fx_where, 4);
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ (oldval | tval), 4);
+ }
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDA21_LO:
+ {
+ int tval = PPC_LO (value);
+ valueT oldval = md_chars_to_number (
+ fixP->fx_frag->fr_literal + fixP->fx_where, 4);
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ (oldval | tval), 4);
+ }
+ break;
+
+ case BFD_RELOC_PPC_VLE_SDA21:
+ {
+ valueT oldval = md_chars_to_number (
+ fixP->fx_frag->fr_literal + fixP->fx_where, 4);
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ (oldval | value), 4);
+ }
+ break;
+
#ifdef OBJ_XCOFF
case BFD_RELOC_NONE:
break;
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
index a11d396..eb19017 100644
--- a/gas/config/tc-ppc.h
+++ b/gas/config/tc-ppc.h
@@ -84,14 +84,11 @@ extern char *ppc_target_format (void);
ppc_handle_align (FRAGP);
extern void ppc_handle_align (struct frag *);
+extern void ppc_frag_check (struct frag *);
#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
-#define md_frag_check(FRAGP) \
- if ((FRAGP)->has_code \
- && (((FRAGP)->fr_address + (FRAGP)->insn_addr) & 3) != 0) \
- as_bad_where ((FRAGP)->fr_file, (FRAGP)->fr_line, \
- _("instruction address is not a multiple of 4"));
+#define md_frag_check(FRAGP) ppc_frag_check (FRAGP)
/* Arrange to store the value of ppc_cpu at the site of a fixup
for later use in md_apply_fix. */
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 5d97e22..251e7d6 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,25 @@
+2012-05-14 Catherine Moore <clm@codesourcery.com>
+ Maciej W. Rozycki <macro@codesourcery.com>
+ Rhonda Wittels <rhonda@codesourcery.com>
+
+ * gas/ppc/ppc.exp: Run new tests.
+ * gas/ppc/vle-reloc.d: New test.
+ * gas/ppc/vle-reloc.s: New test.
+ * gas/ppc/vle-simple-1.d: New test.
+ * gas/ppc/vle-simple-1.s: New test.
+ * gas/ppc/vle-simple-2.d: New test.
+ * gas/ppc/vle-simple-2.s: New test.
+ * gas/ppc/vle-simple-3.d: New test.
+ * gas/ppc/vle-simple-3.s: New test.
+ * gas/ppc/vle-simple-4.d: New test.
+ * gas/ppc/vle-simple-4.s: New test.
+ * gas/ppc/vle-simple-5.d: New test.
+ * gas/ppc/vle-simple-5.s: New test.
+ * gas/ppc/vle-simple-6.d: New test.
+ * gas/ppc/vle-simple-6.s: New test.
+ * gas/ppc/vle.d: New test.
+ * gas/ppc/vle.s: New test.
+
2012-05-14 H.J. Lu <hongjiu.lu@intel.com>
* gas/cris/rd-pic-1.d: Expect addend as signed.
diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp
index ecff355..aac92b6 100644
--- a/gas/testsuite/gas/ppc/ppc.exp
+++ b/gas/testsuite/gas/ppc/ppc.exp
@@ -55,5 +55,13 @@ if { [istarget powerpc*-*-*] } then {
run_dump_test "vsx"
run_dump_test "476"
run_dump_test "titan"
+ run_dump_test "vle"
+ run_dump_test "vle-reloc"
+ run_dump_test "vle-simple-1"
+ run_dump_test "vle-simple-2"
+ run_dump_test "vle-simple-3"
+ run_dump_test "vle-simple-4"
+ run_dump_test "vle-simple-5"
+ run_dump_test "vle-simple-6"
}
}
diff --git a/gas/testsuite/gas/ppc/vle-reloc.d b/gas/testsuite/gas/ppc/vle-reloc.d
new file mode 100644
index 0000000..c272d27
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-reloc.d
@@ -0,0 +1,172 @@
+#as: -mvle
+#objdump: -dr -Mvle
+#name: VLE relocations
+
+.*: +file format elf.*-powerpc.*
+
+Disassembly of section \.text:
+
+00000000 <.text>:
+ 0: e8 00 se_b 0x0
+ 0: R_PPC_VLE_REL8 sub1
+ 2: e9 00 se_bl 0x2
+ 2: R_PPC_VLE_REL8 sub1
+ 4: e1 00 se_ble 0x4
+ 4: R_PPC_VLE_REL8 sub2
+ 6: e6 00 se_beq 0x6
+ 6: R_PPC_VLE_REL8 sub2
+ 8: 78 00 00 00 e_b 0x8
+ 8: R_PPC_VLE_REL24 sub3
+ c: 78 00 00 01 e_bl 0xc
+ c: R_PPC_VLE_REL24 sub4
+ 10: 7a 05 00 00 e_ble cr1,0x10
+ 10: R_PPC_VLE_REL15 sub5
+ 14: 7a 1a 00 01 e_beql cr2,0x14
+ 14: R_PPC_VLE_REL15 sub5
+
+ 18: 70 20 c0 00 e_or2i r1,0
+ 18: R_PPC_VLE_LO16D low
+ 1c: 70 40 c0 00 e_or2i r2,0
+ 1c: R_PPC_VLE_HI16D high
+ 20: 70 60 c0 00 e_or2i r3,0
+ 20: R_PPC_VLE_HA16D high_adjust
+ 24: 70 80 c0 00 e_or2i r4,0
+ 24: R_PPC_VLE_SDAREL_LO16D low_sdarel
+ 28: 70 a0 c0 00 e_or2i r5,0
+ 28: R_PPC_VLE_SDAREL_HI16D high_sdarel
+ 2c: 70 40 c0 00 e_or2i r2,0
+ 2c: R_PPC_VLE_SDAREL_HA16D high_adjust_sdarel
+ 30: 70 20 c8 00 e_and2i. r1,0
+ 30: R_PPC_VLE_LO16D low
+ 34: 70 40 c8 00 e_and2i. r2,0
+ 34: R_PPC_VLE_HI16D high
+ 38: 70 60 c8 00 e_and2i. r3,0
+ 38: R_PPC_VLE_HA16D high_adjust
+ 3c: 70 80 c8 00 e_and2i. r4,0
+ 3c: R_PPC_VLE_SDAREL_LO16D low_sdarel
+ 40: 70 a0 c8 00 e_and2i. r5,0
+ 40: R_PPC_VLE_SDAREL_HI16D high_sdarel
+ 44: 70 40 c8 00 e_and2i. r2,0
+ 44: R_PPC_VLE_SDAREL_HA16D high_adjust_sdarel
+ 48: 70 40 c8 00 e_and2i. r2,0
+ 48: R_PPC_VLE_SDAREL_HA16D high_adjust_sdarel
+ 4c: 70 20 d0 00 e_or2is r1,0
+ 4c: R_PPC_VLE_LO16D low
+ 50: 70 40 d0 00 e_or2is r2,0
+ 50: R_PPC_VLE_HI16D high
+ 54: 70 60 d0 00 e_or2is r3,0
+ 54: R_PPC_VLE_HA16D high_adjust
+ 58: 70 80 d0 00 e_or2is r4,0
+ 58: R_PPC_VLE_SDAREL_LO16D low_sdarel
+ 5c: 70 a0 d0 00 e_or2is r5,0
+ 5c: R_PPC_VLE_SDAREL_HI16D high_sdarel
+ 60: 70 40 d0 00 e_or2is r2,0
+ 60: R_PPC_VLE_SDAREL_HA16D high_adjust_sdarel
+ 64: 70 20 e0 00 e_lis r1,0
+ 64: R_PPC_VLE_LO16D low
+ 68: 70 40 e0 00 e_lis r2,0
+ 68: R_PPC_VLE_HI16D high
+ 6c: 70 60 e0 00 e_lis r3,0
+ 6c: R_PPC_VLE_HA16D high_adjust
+ 70: 70 80 e0 00 e_lis r4,0
+ 70: R_PPC_VLE_SDAREL_LO16D low_sdarel
+ 74: 70 a0 e0 00 e_lis r5,0
+ 74: R_PPC_VLE_SDAREL_HI16D high_sdarel
+ 78: 70 40 e0 00 e_lis r2,0
+ 78: R_PPC_VLE_SDAREL_HA16D high_adjust_sdarel
+ 7c: 70 20 e8 00 e_and2is. r1,0
+ 7c: R_PPC_VLE_LO16D low
+ 80: 70 40 e8 00 e_and2is. r2,0
+ 80: R_PPC_VLE_HI16D high
+ 84: 70 60 e8 00 e_and2is. r3,0
+ 84: R_PPC_VLE_HA16D high_adjust
+ 88: 70 80 e8 00 e_and2is. r4,0
+ 88: R_PPC_VLE_SDAREL_LO16D low_sdarel
+ 8c: 70 a0 e8 00 e_and2is. r5,0
+ 8c: R_PPC_VLE_SDAREL_HI16D high_sdarel
+ 90: 70 40 e8 00 e_and2is. r2,0
+ 90: R_PPC_VLE_SDAREL_HA16D high_adjust_sdarel
+ 94: 70 01 98 00 e_cmp16i r1,0
+ 94: R_PPC_VLE_LO16A low
+ 98: 70 02 98 00 e_cmp16i r2,0
+ 98: R_PPC_VLE_HI16A high
+ 9c: 70 03 98 00 e_cmp16i r3,0
+ 9c: R_PPC_VLE_HA16A high_adjust
+ a0: 70 04 98 00 e_cmp16i r4,0
+ a0: R_PPC_VLE_SDAREL_LO16A low_sdarel
+ a4: 70 05 98 00 e_cmp16i r5,0
+ a4: R_PPC_VLE_SDAREL_HI16A high_sdarel
+ a8: 70 02 98 00 e_cmp16i r2,0
+ a8: R_PPC_VLE_SDAREL_HA16A high_adjust_sdarel
+ ac: 70 01 a8 00 e_cmpl16i r1,0
+ ac: R_PPC_VLE_LO16A low
+ b0: 70 02 a8 00 e_cmpl16i r2,0
+ b0: R_PPC_VLE_HI16A high
+ b4: 70 03 a8 00 e_cmpl16i r3,0
+ b4: R_PPC_VLE_HA16A high_adjust
+ b8: 70 04 a8 00 e_cmpl16i r4,0
+ b8: R_PPC_VLE_SDAREL_LO16A low_sdarel
+ bc: 70 05 a8 00 e_cmpl16i r5,0
+ bc: R_PPC_VLE_SDAREL_HI16A high_sdarel
+ c0: 70 02 a8 00 e_cmpl16i r2,0
+ c0: R_PPC_VLE_SDAREL_HA16A high_adjust_sdarel
+ c4: 70 01 b0 00 e_cmph16i r1,0
+ c4: R_PPC_VLE_LO16A low
+ c8: 70 02 b0 00 e_cmph16i r2,0
+ c8: R_PPC_VLE_HI16A high
+ cc: 70 03 b0 00 e_cmph16i r3,0
+ cc: R_PPC_VLE_HA16A high_adjust
+ d0: 70 04 b0 00 e_cmph16i r4,0
+ d0: R_PPC_VLE_SDAREL_LO16A low_sdarel
+ d4: 70 05 b0 00 e_cmph16i r5,0
+ d4: R_PPC_VLE_SDAREL_HI16A high_sdarel
+ d8: 70 02 b0 00 e_cmph16i r2,0
+ d8: R_PPC_VLE_SDAREL_HA16A high_adjust_sdarel
+ dc: 70 01 b8 00 e_cmphl16i r1,0
+ dc: R_PPC_VLE_LO16A low
+ e0: 70 02 b8 00 e_cmphl16i r2,0
+ e0: R_PPC_VLE_HI16A high
+ e4: 70 03 b8 00 e_cmphl16i r3,0
+ e4: R_PPC_VLE_HA16A high_adjust
+ e8: 70 04 b8 00 e_cmphl16i r4,0
+ e8: R_PPC_VLE_SDAREL_LO16A low_sdarel
+ ec: 70 05 b8 00 e_cmphl16i r5,0
+ ec: R_PPC_VLE_SDAREL_HI16A high_sdarel
+ f0: 70 02 b8 00 e_cmphl16i r2,0
+ f0: R_PPC_VLE_SDAREL_HA16A high_adjust_sdarel
+ f4: 70 01 88 00 e_add2i. r1,0
+ f4: R_PPC_VLE_LO16A low
+ f8: 70 02 88 00 e_add2i. r2,0
+ f8: R_PPC_VLE_HI16A high
+ fc: 70 03 88 00 e_add2i. r3,0
+ fc: R_PPC_VLE_HA16A high_adjust
+ 100: 70 04 88 00 e_add2i. r4,0
+ 100: R_PPC_VLE_SDAREL_LO16A low_sdarel
+ 104: 70 05 88 00 e_add2i. r5,0
+ 104: R_PPC_VLE_SDAREL_HI16A high_sdarel
+ 108: 70 02 88 00 e_add2i. r2,0
+ 108: R_PPC_VLE_SDAREL_HA16A high_adjust_sdarel
+ 10c: 70 01 90 00 e_add2is r1,0
+ 10c: R_PPC_VLE_LO16A low
+ 110: 70 02 90 00 e_add2is r2,0
+ 110: R_PPC_VLE_HI16A high
+ 114: 70 03 90 00 e_add2is r3,0
+ 114: R_PPC_VLE_HA16A high_adjust
+ 118: 70 04 90 00 e_add2is r4,0
+ 118: R_PPC_VLE_SDAREL_LO16A low_sdarel
+ 11c: 70 05 90 00 e_add2is r5,0
+ 11c: R_PPC_VLE_SDAREL_HI16A high_sdarel
+ 120: 70 02 90 00 e_add2is r2,0
+ 120: R_PPC_VLE_SDAREL_HA16A high_adjust_sdarel
+ 124: 70 01 a0 00 e_mull2i r1,0
+ 124: R_PPC_VLE_LO16A low
+ 128: 70 02 a0 00 e_mull2i r2,0
+ 128: R_PPC_VLE_HI16A high
+ 12c: 70 03 a0 00 e_mull2i r3,0
+ 12c: R_PPC_VLE_HA16A high_adjust
+ 130: 70 04 a0 00 e_mull2i r4,0
+ 130: R_PPC_VLE_SDAREL_LO16A low_sdarel
+ 134: 70 05 a0 00 e_mull2i r5,0
+ 134: R_PPC_VLE_SDAREL_HI16A high_sdarel
+ 138: 70 02 a0 00 e_mull2i r2,0
+ 138: R_PPC_VLE_SDAREL_HA16A high_adjust_sdarel
diff --git a/gas/testsuite/gas/ppc/vle-reloc.s b/gas/testsuite/gas/ppc/vle-reloc.s
new file mode 100644
index 0000000..fb2a01a
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-reloc.s
@@ -0,0 +1,95 @@
+ .section .text
+ se_b sub1
+ se_bl sub1
+ se_bc 0,1,sub2
+ se_bc 1,2,sub2
+
+ e_b sub3
+ e_bl sub4
+ e_bc 0,5,sub5
+ e_bcl 1,10,sub5
+
+ e_or2i 1, low@l
+ e_or2i 2, high@h
+ e_or2i 3, high_adjust@ha
+ e_or2i 4, low_sdarel@sdarel@l
+ e_or2i 5, high_sdarel@sdarel@h
+ e_or2i 2, high_adjust_sdarel@sdarel@ha
+
+ e_and2i. 1, low@l
+ e_and2i. 2, high@h
+ e_and2i. 3, high_adjust@ha
+ e_and2i. 4, low_sdarel@sdarel@l
+ e_and2i. 5, high_sdarel@sdarel@h
+ e_and2i. 2, high_adjust_sdarel@sdarel@ha
+ e_and2i. 2, high_adjust_sdarel@sdarel@ha
+
+ e_or2is 1, low@l
+ e_or2is 2, high@h
+ e_or2is 3, high_adjust@ha
+ e_or2is 4, low_sdarel@sdarel@l
+ e_or2is 5, high_sdarel@sdarel@h
+ e_or2is 2, high_adjust_sdarel@sdarel@ha
+
+ e_lis 1, low@l
+ e_lis 2, high@h
+ e_lis 3, high_adjust@ha
+ e_lis 4, low_sdarel@sdarel@l
+ e_lis 5, high_sdarel@sdarel@h
+ e_lis 2, high_adjust_sdarel@sdarel@ha
+
+ e_and2is. 1, low@l
+ e_and2is. 2, high@h
+ e_and2is. 3, high_adjust@ha
+ e_and2is. 4, low_sdarel@sdarel@l
+ e_and2is. 5, high_sdarel@sdarel@h
+ e_and2is. 2, high_adjust_sdarel@sdarel@ha
+
+ e_cmp16i 1, low@l
+ e_cmp16i 2, high@h
+ e_cmp16i 3, high_adjust@ha
+ e_cmp16i 4, low_sdarel@sdarel@l
+ e_cmp16i 5, high_sdarel@sdarel@h
+ e_cmp16i 2, high_adjust_sdarel@sdarel@ha
+
+ e_cmpl16i 1, low@l
+ e_cmpl16i 2, high@h
+ e_cmpl16i 3, high_adjust@ha
+ e_cmpl16i 4, low_sdarel@sdarel@l
+ e_cmpl16i 5, high_sdarel@sdarel@h
+ e_cmpl16i 2, high_adjust_sdarel@sdarel@ha
+
+ e_cmph16i 1, low@l
+ e_cmph16i 2, high@h
+ e_cmph16i 3, high_adjust@ha
+ e_cmph16i 4, low_sdarel@sdarel@l
+ e_cmph16i 5, high_sdarel@sdarel@h
+ e_cmph16i 2, high_adjust_sdarel@sdarel@ha
+
+ e_cmphl16i 1, low@l
+ e_cmphl16i 2, high@h
+ e_cmphl16i 3, high_adjust@ha
+ e_cmphl16i 4, low_sdarel@sdarel@l
+ e_cmphl16i 5, high_sdarel@sdarel@h
+ e_cmphl16i 2, high_adjust_sdarel@sdarel@ha
+
+ e_add2i. 1, low@l
+ e_add2i. 2, high@h
+ e_add2i. 3, high_adjust@ha
+ e_add2i. 4, low_sdarel@sdarel@l
+ e_add2i. 5, high_sdarel@sdarel@h
+ e_add2i. 2, high_adjust_sdarel@sdarel@ha
+
+ e_add2is 1, low@l
+ e_add2is 2, high@h
+ e_add2is 3, high_adjust@ha
+ e_add2is 4, low_sdarel@sdarel@l
+ e_add2is 5, high_sdarel@sdarel@h
+ e_add2is 2, high_adjust_sdarel@sdarel@ha
+
+ e_mull2i 1, low@l
+ e_mull2i 2, high@h
+ e_mull2i 3, high_adjust@ha
+ e_mull2i 4, low_sdarel@sdarel@l
+ e_mull2i 5, high_sdarel@sdarel@h
+ e_mull2i 2, high_adjust_sdarel@sdarel@ha
diff --git a/gas/testsuite/gas/ppc/vle-simple-1.d b/gas/testsuite/gas/ppc/vle-simple-1.d
new file mode 100644
index 0000000..669c703
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-1.d
@@ -0,0 +1,39 @@
+#as: -mvle
+#objdump: -dr -Mvle
+#name: VLE Simplified mnemonics 1
+
+.*: +file format elf.*-powerpc.*
+
+Disassembly of section \.text:
+
+00000000 <target0>:
+ 0: e6 03 se_beq 6 <target3>
+
+00000002 <target1>:
+ 2: e1 03 se_ble 8 <target4>
+
+00000004 <target2>:
+ 4: e0 00 se_bge 4 <target2>
+
+00000006 <target3>:
+ 6: e5 fe se_bgt 2 <target1>
+
+00000008 <target4>:
+ 8: e1 ff se_ble 6 <target3>
+ a: e4 03 se_blt 10 <target6>
+
+0000000c <target5>:
+ c: e2 fb se_bne 2 <target1>
+ e: e1 01 se_ble 10 <target6>
+
+00000010 <target6>:
+ 10: e0 fc se_bge 8 <target4>
+ 12: e3 fd se_bns c <target5>
+
+00000014 <target8>:
+ 14: e3 f8 se_bns 4 <target2>
+ 16: e7 ff se_bso 14 <target8>
+
+00000018 <target9>:
+ 18: e6 fc se_beq 10 <target6>
+ 1a: e7 ff se_bso 18 <target9>
diff --git a/gas/testsuite/gas/ppc/vle-simple-1.s b/gas/testsuite/gas/ppc/vle-simple-1.s
new file mode 100644
index 0000000..bbd7c7b
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-1.s
@@ -0,0 +1,34 @@
+ .section .text
+
+target0:
+ se_beq target3
+
+target1:
+ se_bf cr1, target4
+
+target2:
+ se_bge target2
+
+target3:
+ se_bgt target1
+
+target4:
+ se_ble target3
+ se_blt target6
+
+target5:
+ se_bne target1
+ se_bng target6
+
+target6:
+ se_bnl target4
+ se_bns target5
+
+target8:
+ se_bnu target2
+ se_bso target8
+
+target9:
+ se_bt cr2, target6
+ se_bun target9
+
diff --git a/gas/testsuite/gas/ppc/vle-simple-2.d b/gas/testsuite/gas/ppc/vle-simple-2.d
new file mode 100644
index 0000000..d24ff44
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-2.d
@@ -0,0 +1,83 @@
+#as: -mvle
+#objdump: -dr -Mvle
+#name: VLE Simplified mnemonics 2
+
+.*: +file format elf.*-powerpc.*
+
+Disassembly of section .text:
+
+00000000 <target0>:
+ 0: 7a 20 00 0c e_bdnz c <target1>
+ 4: 7a 20 00 09 e_bdnzl c <target1>
+ 8: 7a 30 00 10 e_bdz 18 <target2>
+
+0000000c <target1>:
+ c: 7a 30 ff f5 e_bdzl 0 <target0>
+ 10: 7a 12 ff f0 e_beq 0 <target0>
+ 14: 7a 16 00 8c e_beq cr1,a0 <target8>
+
+00000018 <target2>:
+ 18: 7a 12 ff f5 e_beql c <target1>
+ 1c: 7a 12 00 4d e_beql 68 <target6>
+ 20: 7a 01 00 04 e_ble 24 <target3>
+
+00000024 <target3>:
+ 24: 7a 03 ff dd e_bnsl 0 <target0>
+ 28: 7a 04 ff e4 e_bge cr1,c <target1>
+ 2c: 7a 00 00 24 e_bge 50 <target5>
+
+00000030 <target4>:
+ 30: 7a 08 ff f5 e_bgel cr2,24 <target3>
+ 34: 7a 00 ff fd e_bgel 30 <target4>
+ 38: 7a 11 ff c8 e_bgt 0 <target0>
+ 3c: 7a 11 ff c4 e_bgt 0 <target0>
+ 40: 7a 19 ff d9 e_bgtl cr2,18 <target2>
+ 44: 7a 11 ff d5 e_bgtl 18 <target2>
+ 48: 7a 0d 00 08 e_ble cr3,50 <target5>
+ 4c: 7a 01 00 04 e_ble 50 <target5>
+
+00000050 <target5>:
+ 50: 7a 01 ff e1 e_blel 30 <target4>
+ 54: 7a 01 ff dd e_blel 30 <target4>
+ 58: 7a 14 ff cc e_blt cr1,24 <target3>
+ 5c: 7a 10 ff c8 e_blt 24 <target3>
+ 60: 7a 10 ff a1 e_bltl 0 <target0>
+ 64: 7a 14 ff 9d e_bltl cr1,0 <target0>
+
+00000068 <target6>:
+ 68: 7a 02 00 18 e_bne 80 <target7>
+ 6c: 7a 06 ff 94 e_bne cr1,0 <target0>
+ 70: 7a 02 ff e1 e_bnel 50 <target5>
+ 74: 7a 02 ff dd e_bnel 50 <target5>
+ 78: 7a 01 00 48 e_ble c0 <target9>
+ 7c: 7a 05 ff b4 e_ble cr1,30 <target4>
+
+00000080 <target7>:
+ 80: 7a 09 ff e9 e_blel cr2,68 <target6>
+ 84: 7a 01 00 1d e_blel a0 <target8>
+ 88: 7a 04 ff c8 e_bge cr1,50 <target5>
+ 8c: 7a 00 ff c4 e_bge 50 <target5>
+ 90: 7a 0c ff 95 e_bgel cr3,24 <target3>
+ 94: 7a 00 ff 91 e_bgel 24 <target3>
+ 98: 7a 03 ff 80 e_bns 18 <target2>
+ 9c: 7a 03 ff 7c e_bns 18 <target2>
+
+000000a0 <target8>:
+ a0: 7a 0b ff 61 e_bnsl cr2,0 <target0>
+ a4: 7a 03 ff c5 e_bnsl 68 <target6>
+ a8: 7a 07 ff 64 e_bns cr1,c <target1>
+ ac: 7a 03 ff 60 e_bns c <target1>
+ b0: 7a 03 ff d1 e_bnsl 80 <target7>
+ b4: 7a 03 ff 71 e_bnsl 24 <target3>
+ b8: 7a 17 ff 78 e_bso cr1,30 <target4>
+ bc: 7a 13 ff 74 e_bso 30 <target4>
+
+000000c0 <target9>:
+ c0: 7a 13 ff e1 e_bsol a0 <target8>
+ c4: 7a 13 ff dd e_bsol a0 <target8>
+ c8: 7a 11 ff b8 e_bgt 80 <target7>
+ cc: 7a 10 ff 85 e_bltl 50 <target5>
+ d0: 7a 17 ff 60 e_bso cr1,30 <target4>
+ d4: 7a 13 ff 5c e_bso 30 <target4>
+ d8: 7a 1b ff 29 e_bsol cr2,0 <target0>
+ dc: 7a 13 ff e5 e_bsol c0 <target9>
diff --git a/gas/testsuite/gas/ppc/vle-simple-2.s b/gas/testsuite/gas/ppc/vle-simple-2.s
new file mode 100644
index 0000000..73b3277
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-2.s
@@ -0,0 +1,78 @@
+ .section .text
+
+target0:
+ e_bdnz target1
+ e_bdnzl target1
+ e_bdz target2
+
+target1:
+ e_bdzl target0
+ e_beq target0
+ e_beq cr1, target8
+
+target2:
+ e_beql cr0, target1
+ e_beql target6
+ e_bf cr1, target3
+
+target3:
+ e_bfl cr3, target0
+ e_bge cr1, target1
+ e_bge target5
+
+target4:
+ e_bgel cr2, target3
+ e_bgel target4
+ e_bgt cr0, target0
+ e_bgt target0
+ e_bgtl cr2, target2
+ e_bgtl target2
+ e_ble cr3, target5
+ e_ble target5
+
+target5:
+ e_blel cr0, target4
+ e_blel target4
+ e_blt cr1, target3
+ e_blt target3
+ e_bltl target0
+ e_bltl cr1, target0
+
+target6:
+ e_bne target7
+ e_bne cr1, target0
+ e_bnel cr0, target5
+ e_bnel target5
+ e_bng target9
+ e_bng cr1, target4
+
+target7:
+ e_bngl cr2, target6
+ e_bngl target8
+ e_bnl cr1, target5
+ e_bnl target5
+ e_bnll cr3, target3
+ e_bnll target3
+ e_bns target2
+ e_bns cr0, target2
+
+target8:
+ e_bnsl cr2, target0
+ e_bnsl target6
+ e_bnu cr1, target1
+ e_bnu target1
+ e_bnul target7
+ e_bnul cr0, target3
+ e_bso cr1, target4
+ e_bso target4
+
+target9:
+ e_bsol cr0, target8
+ e_bsol target8
+ e_bt cr1, target7
+ e_btl cr0, target5
+ e_bun cr1, target4
+ e_bun target4
+ e_bunl cr2, target0
+ e_bunl target9
+
diff --git a/gas/testsuite/gas/ppc/vle-simple-3.d b/gas/testsuite/gas/ppc/vle-simple-3.d
new file mode 100644
index 0000000..6bf700e
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-3.d
@@ -0,0 +1,24 @@
+#as: -mvle
+#objdump: -dr -Mvle
+#name: VLE Simplified mnemonics 3
+
+.*: +file format elf.*-powerpc.*
+
+Disassembly of section .text:
+
+00000000 <trap>:
+ 0: 7f e0 00 08 trap
+ 4: 7e 01 10 08 twlt r1,r2
+ 8: 7e 83 20 08 twle r3,r4
+ c: 7c 80 08 08 tweq r0,r1
+ 10: 7d 82 18 08 twge r2,r3
+ 14: 7d 02 20 08 twgt r2,r4
+ 18: 7d 82 28 08 twge r2,r5
+ 1c: 7f 02 30 08 twne r2,r6
+ 20: 7e 82 38 08 twle r2,r7
+ 24: 7c 42 40 08 twllt r2,r8
+ 28: 7c c2 48 08 twlle r2,r9
+ 2c: 7c a2 50 08 twlge r2,r10
+ 30: 7c 22 58 08 twlgt r2,r11
+ 34: 7c a2 60 08 twlge r2,r12
+ 38: 7c c2 68 08 twlle r2,r13
diff --git a/gas/testsuite/gas/ppc/vle-simple-3.s b/gas/testsuite/gas/ppc/vle-simple-3.s
new file mode 100644
index 0000000..a0d7d80
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-3.s
@@ -0,0 +1,18 @@
+ .section .text
+trap:
+ trap
+ twlt 1, 2
+ twle 3, 4
+ tweq 0, 1
+ twge 2, 3
+ twgt 2, 4
+ twnl 2, 5
+ twne 2, 6
+ twng 2, 7
+ twllt 2, 8
+ twlle 2, 9
+ twlge 2, 10
+ twlgt 2, 11
+ twlnl 2, 12
+ twlng 2, 13
+
diff --git a/gas/testsuite/gas/ppc/vle-simple-4.d b/gas/testsuite/gas/ppc/vle-simple-4.d
new file mode 100644
index 0000000..2dc6202
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-4.d
@@ -0,0 +1,23 @@
+#as: -mvle
+#objdump: -dr -Mvle
+#name: VLE Simplified mnemonics 4
+
+.*: +file format elf.*-powerpc.*
+
+Disassembly of section .text:
+
+00000000 <subtract>:
+ 0: 7c 23 10 50 subf r1,r3,r2
+ 4: 7c a3 20 51 subf. r5,r3,r4
+ 8: 7c 21 14 50 subfo r1,r1,r2
+ c: 7c 01 14 51 subfo. r0,r1,r2
+ 10: 7c 65 20 10 subfc r3,r5,r4
+ 14: 7c 65 20 11 subfc. r3,r5,r4
+ 18: 7c 23 14 10 subfco r1,r3,r2
+ 1c: 7c a7 34 11 subfco. r5,r7,r6
+ 20: 18 85 84 d0 e_addi r4,r5,-48
+ 24: 18 66 94 fe e_addic r3,r6,-2
+ 28: 18 e8 9c f0 e_addic. r7,r8,-16
+ 2c: 1c 22 ff f1 e_add16i r1,r2,-15
+ 30: 73 e5 8f ff e_add2i. r5,-1
+ 34: 73 ea 97 00 e_add2is r10,-256
diff --git a/gas/testsuite/gas/ppc/vle-simple-4.s b/gas/testsuite/gas/ppc/vle-simple-4.s
new file mode 100755
index 0000000..5a7befd
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-4.s
@@ -0,0 +1,19 @@
+ .section .text
+
+subtract:
+ sub 1, 2, 3
+ sub. 5, 4, 3
+ subo 1, 2, 1
+ subo. 0, 2, 1
+ subc 3, 4, 5
+ subc. 3, 4, 5
+ subco 1, 2, 3
+ subco. 5, 6, 7
+
+ e_subi 4, 5, 0x30
+ e_subic 3, 6, 0x2
+ e_subic. 7, 8, 0x10
+
+ e_sub16i 1, 2, 0xf
+ e_sub2i. 5, 0x1
+ e_sub2is 10, 0x100
diff --git a/gas/testsuite/gas/ppc/vle-simple-5.d b/gas/testsuite/gas/ppc/vle-simple-5.d
new file mode 100644
index 0000000..f5cc6a5
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-5.d
@@ -0,0 +1,20 @@
+#as: -mvle
+#objdump: -dr -Mvle
+#name: VLE Simplified mnemonics 5
+
+.*: +file format elf.*-powerpc.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 74 42 00 01 e_rlwinm r2,r2,0,0,0
+ 4: 74 62 7d bf e_rlwinm r2,r3,15,22,31
+ 8: 74 a4 f8 48 e_rlwimi r4,r5,31,1,4
+ c: 74 e6 c9 4c e_rlwimi r6,r7,25,5,6
+ 10: 74 41 50 3f e_rlwinm r1,r2,10,0,31
+ 14: 74 83 c0 3f e_rlwinm r3,r4,24,0,31
+ 18: 7c 62 f8 70 e_slwi r2,r3,31
+ 1c: 7c 25 f4 70 e_srwi r5,r1,30
+ 20: 74 64 07 7f e_rlwinm r4,r3,0,29,31
+ 24: 74 41 00 07 e_rlwinm r1,r2,0,0,3
+ 28: 74 e6 d8 49 e_rlwinm r6,r7,27,1,4
diff --git a/gas/testsuite/gas/ppc/vle-simple-5.s b/gas/testsuite/gas/ppc/vle-simple-5.s
new file mode 100644
index 0000000..e7a2d9b
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-5.s
@@ -0,0 +1,13 @@
+ .section .text
+
+ e_extlwi 2, 2, 1, 0
+ e_extrwi 2, 3, 10, 5
+ e_inslwi 4, 5, 4, 1
+ e_insrwi 6, 7, 2, 5
+ e_rotlwi 1, 2, 10
+ e_rotrwi 3, 4, 8
+ e_slwi 2, 3, 31
+ e_srwi 5, 1, 30
+ e_clrlwi 4, 3, 29
+ e_clrrwi 1, 2, 28
+ e_clrlslwi 6, 7, 28, 27
diff --git a/gas/testsuite/gas/ppc/vle-simple-6.d b/gas/testsuite/gas/ppc/vle-simple-6.d
new file mode 100644
index 0000000..f94f223
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-6.d
@@ -0,0 +1,60 @@
+#as: -mvle
+#objdump: -dr -Mvle
+#name: VLE Simplified mnemonics 6
+
+.*: +file format elf.*-powerpc.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 7c b1 9b a6 mtmas1 r5
+ 4: 7c 3a 0b a6 mtcsrr0 r1
+ 8: 7c 5b 0b a6 mtcsrr1 r2
+ c: 7c b0 62 a6 mfivor0 r5
+ 10: 7c b1 62 a6 mfivor1 r5
+ 14: 7c b2 62 a6 mfivor2 r5
+ 18: 7c b3 62 a6 mfivor3 r5
+ 1c: 7c b4 62 a6 mfivor4 r5
+ 20: 7c b5 62 a6 mfivor5 r5
+ 24: 7c b6 62 a6 mfivor6 r5
+ 28: 7c b7 62 a6 mfivor7 r5
+ 2c: 7c b8 62 a6 mfivor8 r5
+ 30: 7c b9 62 a6 mfivor9 r5
+ 34: 7c ba 62 a6 mfivor10 r5
+ 38: 7c bb 62 a6 mfivor11 r5
+ 3c: 7c bc 62 a6 mfivor12 r5
+ 40: 7c bd 62 a6 mfivor13 r5
+ 44: 7c be 62 a6 mfivor14 r5
+ 48: 7c bf 62 a6 mfivor15 r5
+ 4c: 7d 50 43 a6 mtsprg 0,r10
+ 50: 7d 51 43 a6 mtsprg 1,r10
+ 54: 7d 52 43 a6 mtsprg 2,r10
+ 58: 7d 53 43 a6 mtsprg 3,r10
+ 5c: 7d 54 43 a6 mtsprg 4,r10
+ 60: 7d 55 43 a6 mtsprg 5,r10
+ 64: 7d 56 43 a6 mtsprg 6,r10
+ 68: 7d 57 43 a6 mtsprg 7,r10
+ 6c: 7d 50 43 a6 mtsprg 0,r10
+ 70: 7d 51 43 a6 mtsprg 1,r10
+ 74: 7d 52 43 a6 mtsprg 2,r10
+ 78: 7d 53 43 a6 mtsprg 3,r10
+ 7c: 7d 54 43 a6 mtsprg 4,r10
+ 80: 7d 55 43 a6 mtsprg 5,r10
+ 84: 7d 56 43 a6 mtsprg 6,r10
+ 88: 7d 57 43 a6 mtsprg 7,r10
+ 8c: 7d 30 42 a6 mfsprg r9,0
+ 90: 7d 31 42 a6 mfsprg r9,1
+ 94: 7d 32 42 a6 mfsprg r9,2
+ 98: 7d 33 42 a6 mfsprg r9,3
+ 9c: 7d 24 42 a6 mfsprg r9,4
+ a0: 7d 25 42 a6 mfsprg r9,5
+ a4: 7d 26 42 a6 mfsprg r9,6
+ a8: 7d 27 42 a6 mfsprg r9,7
+ ac: 7d 30 42 a6 mfsprg r9,0
+ b0: 7d 31 42 a6 mfsprg r9,1
+ b4: 7d 32 42 a6 mfsprg r9,2
+ b8: 7d 33 42 a6 mfsprg r9,3
+ bc: 7d 24 42 a6 mfsprg r9,4
+ c0: 7d 25 42 a6 mfsprg r9,5
+ c4: 7d 26 42 a6 mfsprg r9,6
+ c8: 7d 27 42 a6 mfsprg r9,7
diff --git a/gas/testsuite/gas/ppc/vle-simple-6.s b/gas/testsuite/gas/ppc/vle-simple-6.s
new file mode 100644
index 0000000..4d10dd7
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle-simple-6.s
@@ -0,0 +1,59 @@
+ .section .text
+
+ mtmas1 5
+
+ mtcsrr0 1
+ mtcsrr1 2
+
+ mfivor0 5
+ mfivor1 5
+ mfivor2 5
+ mfivor3 5
+ mfivor4 5
+ mfivor5 5
+ mfivor6 5
+ mfivor7 5
+ mfivor8 5
+ mfivor9 5
+ mfivor10 5
+ mfivor11 5
+ mfivor12 5
+ mfivor13 5
+ mfivor14 5
+ mfivor15 5
+
+ mtsprg 0, 10
+ mtsprg 1, 10
+ mtsprg 2, 10
+ mtsprg 3, 10
+ mtsprg 4, 10
+ mtsprg 5, 10
+ mtsprg 6, 10
+ mtsprg 7, 10
+
+ mtsprg0 10
+ mtsprg1 10
+ mtsprg2 10
+ mtsprg3 10
+ mtsprg4 10
+ mtsprg5 10
+ mtsprg6 10
+ mtsprg7 10
+
+ mfsprg 9, 0
+ mfsprg 9, 1
+ mfsprg 9, 2
+ mfsprg 9, 3
+ mfsprg 9, 4
+ mfsprg 9, 5
+ mfsprg 9, 6
+ mfsprg 9, 7
+
+ mfsprg0 9
+ mfsprg1 9
+ mfsprg2 9
+ mfsprg3 9
+ mfsprg4 9
+ mfsprg5 9
+ mfsprg6 9
+ mfsprg7 9
diff --git a/gas/testsuite/gas/ppc/vle.d b/gas/testsuite/gas/ppc/vle.d
new file mode 100755
index 0000000..2bbe60b
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle.d
@@ -0,0 +1,150 @@
+#as: -mvle
+#objdump: -dr -Mvle
+#name: Validate VLE instructions
+
+.*: +file format elf.*-powerpc.*
+
+Disassembly of section \.text:
+
+0+00 <.*>:
+ 0: 1c 83 00 1b e_add16i r4,r3,27
+ 4: 70 c0 8c 56 e_add2i\. r0,13398
+ 8: 71 01 93 21 e_add2is r1,17185
+ c: 18 46 88 37 e_addi\. r2,r6,55
+ 10: 18 65 81 37 e_addi r3,r5,14080
+ 14: 18 84 9a 37 e_addic\. r4,r4,3604480
+ 18: 18 e8 93 37 e_addic r7,r8,922746880
+ 1c: 71 3f ce ed e_and2i\. r9,65261
+ 20: 71 40 e8 05 e_and2is\. r10,5
+ 24: 19 ab c8 39 e_andi\. r11,r13,57
+ 28: 19 ec c2 37 e_andi r12,r15,3604480
+ 2c: 78 00 00 ec e_b 118 <middle_label>
+ 30: 78 00 00 01 e_bl 30 <start_label\+0x30>
+ 30: R_PPC_VLE_REL24 extern_subr
+ 34: 7a 03 ff cc e_bns 0 <start_label>
+ 38: 7a 1f 00 01 e_bsol cr3,38 <start_label\+0x38>
+ 38: R_PPC_VLE_REL15 extern_subr
+ 3c: 70 c2 9b 33 e_cmp16i r2,13107
+ 40: 18 46 a9 37 e_cmpi cr2,r6,14080
+ 44: 7c 87 58 1c e_cmph cr1,r7,r11
+ 48: 73 ec b5 ef e_cmph16i r12,-529
+ 4c: 7c 06 40 5c e_cmphl cr0,r6,r8
+ 50: 70 4d ba 34 e_cmphl16i r13,4660
+ 54: 73 e1 ae e0 e_cmpl16i r1,65248
+ 58: 18 a3 ab 37 e_cmpli cr1,r3,922746880
+ 5c: 7f a3 02 02 e_crand 4\*cr7\+gt,so,lt
+ 60: 7c 02 e9 02 e_crandc lt,eq,4\*cr7\+gt
+ 64: 7d f0 8a 42 e_creqv 4\*cr3\+so,4\*cr4\+lt,4\*cr4\+gt
+ 68: 7d e0 19 c2 e_crnand 4\*cr3\+so,lt,so
+ 6c: 7d e0 18 42 e_crnor 4\*cr3\+so,lt,so
+ 70: 7d 8d 73 82 e_cror 4\*cr3\+lt,4\*cr3\+gt,4\*cr3\+eq
+ 74: 7e 72 8b 42 e_crorc 4\*cr4\+so,4\*cr4\+eq,4\*cr4\+gt
+ 78: 7c 00 01 82 e_crclr lt
+ 7c: 30 e3 cc 0d e_lbz r7,-13299\(r3\)
+ 80: 18 e5 00 cc e_lbzu r7,-52\(r5\)
+ 84: 39 0a 01 ff e_lha r8,511\(r10\)
+ 88: 19 01 03 ff e_lhau r8,-1\(r1\)
+ 8c: 58 e0 18 38 e_lhz r7,6200\(0\)
+ 90: 18 e0 01 3e e_lhzu r7,62\(0\)
+ 94: 70 06 1b 33 e_li r0,209715
+ 98: 70 26 e3 33 e_lis r1,13107
+ 9c: 18 a3 08 18 e_lmw r5,24\(r3\)
+ a0: 50 a3 27 28 e_lwz r5,10024\(r3\)
+ a4: 18 c2 02 72 e_lwzu r6,114\(r2\)
+ a8: 7c 98 00 20 e_mcrf cr1,cr6
+ ac: 19 2a a0 37 e_mulli r9,r10,55
+ b0: 70 01 a6 68 e_mull2i r1,1640
+ b4: 70 a4 c3 45 e_or2i r5,9029
+ b8: 70 b4 d3 45 e_or2is r5,41797
+ bc: 19 27 d8 37 e_ori\. r7,r9,55
+ c0: 19 07 d1 37 e_ori r7,r8,14080
+ c4: 7e d2 02 30 e_rlw r18,r22,r0
+ c8: 7c 48 02 31 e_rlw\. r8,r2,r0
+ cc: 7c 74 aa 70 e_rlwi r20,r3,21
+ d0: 7c 62 aa 71 e_rlwi\. r2,r3,21
+ d4: 76 64 6a 1e e_rlwimi r4,r19,13,8,15
+ d8: 74 24 68 63 e_rlwinm r4,r1,13,1,17
+ dc: 7e 6c 30 70 e_slwi r12,r19,6
+ e0: 7d 4c a0 71 e_slwi\. r12,r10,20
+ e4: 7c 20 84 70 e_srwi r0,r1,16
+ e8: 7c 20 5c 71 e_srwi\. r0,r1,11
+ ec: 34 61 55 f0 e_stb r3,22000\(r1\)
+ f0: 1a 76 04 fc e_stbu r19,-4\(r22\)
+ f4: 5c 15 02 9a e_sth r0,666\(r21\)
+ f8: 18 37 05 ff e_sthu r1,-1\(r23\)
+ fc: 18 03 09 04 e_stmw r0,4\(r3\)
+ 100: 54 60 3f 21 e_stw r3,16161\(0\)
+ 104: 1a c4 06 ee e_stwu r22,-18\(r4\)
+ 108: 18 15 b2 37 e_subfic r0,r21,3604480
+ 10c: 1a c0 bb 37 e_subfic\. r22,r0,922746880
+ 110: 18 75 e1 37 e_xori r21,r3,14080
+ 114: 1a 80 e8 37 e_xori\. r0,r20,55
+0+0000118 <middle_label>:
+ 118: 04 7f se_add r31,r7
+ 11a: 21 ec se_addi r28,31
+ 11c: 46 10 se_and r0,r1
+ 11e: 47 01 se_and\. r1,r0
+ 120: 45 32 se_andc r2,r3
+ 122: 2f 14 se_andi r4,17
+ 124: e8 fa se_b 118 <middle_label>
+ 126: e9 00 se_bl 126 <middle_label\+0xe>
+ 126: R_PPC_VLE_REL8 extern_subr
+ 128: e7 14 se_bso 150 <not_end_label>
+ 12a: 61 2b se_bclri r27,18
+ 12c: 00 06 se_bctr
+ 12e: 00 07 se_bctrl
+ 130: 63 17 se_bgeni r7,17
+ 132: 00 04 se_blr
+ 134: 00 05 se_blrl
+ 136: 2c 06 se_bmaski r6,0
+ 138: 64 10 se_bseti r0,1
+ 13a: 66 74 se_btsti r4,7
+ 13c: 0c 10 se_cmp r0,r1
+ 13e: 0e cf se_cmph r31,r28
+ 140: 0f 91 se_cmphl r1,r25
+ 142: 2b 63 se_cmpi r3,22
+ 144: 0d 76 se_cmpl r6,r7
+ 146: 22 bc se_cmpli r28,12
+ 148: 00 d1 se_extsb r1
+ 14a: 00 f2 se_extsh r2
+ 14c: 00 ce se_extzb r30
+ 14e: 00 e8 se_extzh r24
+0+0000150 <not_end_label>:
+ 150: 00 00 se_illegal
+ 152: 00 01 se_isync
+ 154: 88 18 se_lbz r1,8\(r24\)
+ 156: a9 84 se_lhz r24,18\(r4\)
+ 158: 4c f4 se_li r4,79
+ 15a: cf 60 se_lwz r6,60\(r0\)
+ 15c: 03 07 se_mfar r7,r8
+ 15e: 00 a3 se_mfctr r3
+ 160: 00 84 se_mflr r4
+ 162: 01 0f se_mr r31,r0
+ 164: 02 2f se_mtar r23,r2
+ 166: 00 b6 se_mtctr r6
+ 168: 00 9f se_mtlr r31
+ 16a: 05 43 se_mullw r3,r4
+ 16c: 00 38 se_neg r24
+ 16e: 00 29 se_not r25
+ 170: 44 10 se_or r0,r1
+ 172: 00 09 se_rfci
+ 174: 00 0a se_rfdi
+ 176: 00 08 se_rfi
+ 178: 00 02 se_sc
+ 17a: 42 65 se_slw r5,r6
+ 17c: 6c 77 se_slwi r7,7
+ 17e: 41 e6 se_sraw r6,r30
+ 180: 6a 89 se_srawi r25,8
+ 182: 40 0e se_srw r30,r0
+ 184: 69 9d se_srwi r29,25
+ 186: 9a 02 se_stb r0,10\(r2\)
+ 188: b6 1e se_sth r1,12\(r30\)
+ 18a: d0 7d se_stw r7,0\(r29\)
+ 18c: 06 21 se_sub r1,r2
+ 18e: 07 ad se_subf r29,r26
+ 190: 25 77 se_subi r7,24
+0+0000192 <end_label>:
+ 192: 27 29 se_subi\. r25,19
+ 194: e9 c2 se_bl 118 <middle_label>
+ 196: 79 ff ff 82 e_b 118 <middle_label>
+ 19a: 79 ff fe 67 e_bl 0 <start_label>
diff --git a/gas/testsuite/gas/ppc/vle.s b/gas/testsuite/gas/ppc/vle.s
new file mode 100755
index 0000000..698d618
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vle.s
@@ -0,0 +1,184 @@
+# Freescale PowerPC VLE instruction tests
+#as: -mvle
+ .section .text
+ .extern extern_subr
+ .equ UI8,0x37
+ .equ SCI0,UI8<<0
+ .equ SCI1,UI8<<8
+ .equ SCI2,UI8<<16
+ .equ SCI3,UI8<<24
+ .equ r0,0
+ .equ r1,1
+ .equ r2,2
+ .equ r3,3
+ .equ r4,4
+ .equ r5,5
+ .equ r6,6
+ .equ r7,7
+ .equ r8,8
+ .equ r9,9
+ .equ r10,10
+ .equ r11,11
+ .equ r12,12
+ .equ r13,13
+ .equ r14,14
+ .equ r15,15
+ .equ r16,16
+ .equ r17,17
+ .equ r18,18
+ .equ r19,19
+ .equ r20,20
+ .equ r21,21
+ .equ r22,22
+ .equ r23,23
+ .equ r24,24
+ .equ r25,25
+ .equ r26,26
+ .equ r27,27
+ .equ r28,28
+ .equ r29,29
+ .equ r30,30
+ .equ r31,31
+ .equ r32,32
+ .equ rsp,r1
+
+
+start_label:
+ e_add16i r4,r3,27
+ e_add2i. r0,0x3456
+ e_add2is r1,0x4321
+ e_addi. r2,r6,SCI0
+ e_addi r3,r5,SCI1
+ e_addic. r4,r4,SCI2
+ e_addic r7,r8,SCI3
+ e_and2i. r9,0xfeed
+ e_and2is. r10,5
+ e_andi. r11,r13,0x39
+ e_andi r12,r15,SCI2
+ e_b middle_label
+ e_bl extern_subr
+ e_bc 0,3,start_label
+ e_bcl 1,15,extern_subr
+ e_cmp16i r2,0x3333
+ e_cmpi 2,r6,SCI1
+ e_cmph 1,r7,r11
+ e_cmph16i r12,0xfdef
+ e_cmphl 0,r6,r8
+ e_cmphl16i r13,0x1234
+ e_cmpl16i r1, 0xfee0
+ e_cmpli 1,r3,SCI3
+ e_crand 0x1d,3,0
+ e_crandc 0,2,0x1d
+ e_creqv 15,16,17
+ e_crnand 0xf,0,3
+ e_crnor 0xf,0,3
+ e_cror 12,13,14
+ e_crorc 19,18,17
+ e_crxor 0,0,0
+ e_lbz r7,0xffffcc0d(r3)
+ e_lbzu r7,-52(r5)
+ e_lha r8,0x1ff(r10)
+ e_lhau r8,-1(r1)
+ e_lhz r7,6200(r0)
+ e_lhzu r7,62(r0)
+ e_li r0,0x33333
+ e_lis r1,0x3333
+ e_lmw r5,24(r3)
+ e_lwz r5,10024(r3)
+ e_lwzu r6,0x72(r2)
+ e_mcrf 1,6
+ e_mulli r9,r10,SCI0
+ e_mull2i r1,0x668
+ e_or2i r5,0x2345
+ e_or2is r5,0xa345
+ e_ori. r7,r9,SCI0
+ e_ori r7,r8,SCI1
+ e_rlw r18, r22,r0
+ e_rlw. r8, r2,r0
+ e_rlwi r20,r3,21
+ e_rlwi. r2,r3,21
+ e_rlwimi r4,r19,13,8,15
+ e_rlwinm r4,r1,13,1,17
+ e_slwi r12,r19,6
+ e_slwi. r12,r10,20
+ e_srwi r0,r1,16
+ e_srwi. r0,r1,11
+ e_stb r3,22000(r1)
+ e_stbu r19,-4(r22)
+ e_sth r0,666(r21)
+ e_sthu r1,-1(r23)
+ e_stmw r0,4(r3)
+ e_stw r3,16161(r0)
+ e_stwu r22,0xffffffee(r4)
+ e_subfic r0,r21,SCI2
+ e_subfic. r22,r0,SCI3
+ e_xori r21,r3,SCI1
+ e_xori. r0,r20,SCI0
+middle_label:
+ se_add r31,r7
+ se_addi r28,0x1f
+ se_and r0,r1
+ se_and. r1,r0
+ se_andc r2, r3
+ se_andi r4,0x11
+ se_b middle_label
+ se_bl extern_subr
+ se_bc 1,3,not_end_label
+ se_bclri r27,0x12
+ se_bctr
+ se_bctrl
+ se_bgeni r7,17
+ se_blr
+ se_blrl
+ se_bmaski r6,0
+ se_bseti r0,1
+ se_btsti r4,7
+ se_cmp r0,r1
+ se_cmph r31,r28
+ se_cmphl r1,r25
+ se_cmpi r3,22
+ se_cmpl r6,r7
+ se_cmpli r28,0xc
+ se_extsb r1
+ se_extsh r2
+ se_extzb r30
+ se_extzh r24
+not_end_label:
+ se_illegal
+ se_isync
+ se_lbz r1,8(r24)
+ se_lhz r24,18(r4)
+ se_li r4,0x4f
+ se_lwz r6,60(r0)
+ se_mfar r7,r8
+ se_mfctr r3
+ se_mflr r4
+ se_mr r31,r0
+ se_mtar r23,r2
+ se_mtctr r6
+ se_mtlr r31
+ se_mullw r3,r4
+ se_neg r24
+ se_not r25
+ se_or r0,r1
+ se_rfci
+ se_rfdi
+ se_rfi
+ se_sc
+ se_slw r5,r6
+ se_slwi r7,7
+ se_sraw r6,r30
+ se_srawi r25,8
+ se_srw r30,r0
+ se_srwi r29,25
+ se_stb r0,10(r2)
+ se_sth r1,12(r30)
+ se_stw r7,0(r29)
+ se_sub r1,r2
+ se_subf r29,r26
+ se_subi r7,24
+end_label:
+ se_subi. r25,19
+ se_bl middle_label
+ e_b middle_label
+ e_bl start_label