From 9b4e57660d385d9135549aeb8360ebfa14fb3990 Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Sat, 2 Aug 2008 04:38:51 +0000 Subject: [PATCH] gas/ * config/tc-ppc.c (parse_cpu): Rename altivec_or_spe to retain_flags. Handle -mvsx and -mpower7. (md_show_usage): Document -mpower7 and -mvsx. * doc/as.texinfo (Target PowerPC): Document -mvsx. * doc/c-ppc.texi (PowerPC-Opts): Document -mvsx and -mpower7. gas/testsuite/ * gas/ppc/power7.d: New. * gas/ppc/power7.s: Likewise. * gas/ppc/ppc.exp: Run power7 test. include/opcode/ * ppc.h (PPC_OPCODE_VSX, PPC_OPERAND_VSR): New. opcodes/ * ppc-dis.c (powerpc_init_dialect): Handle power7 and vsx options. (print_insn_powerpc): Prepend 'vs' when printing VSX registers. (print_ppc_disassembler_options): Document -Mpower7 and -Mvsx. * ppc-opc.c (insert_xt6): New static function. (extract_xt6): Likewise. (insert_xa6): Likewise. (extract_xa6: Likewise. (insert_xb6): Likewise. (extract_xb6): Likewise. (insert_xb6s): Likewise. (extract_xb6s): Likewise. (XS6, XT6, XA6, XB6, XB6S, DM, XX3, XX3DM, XX1_MASK, XX3_MASK, XX3DM_MASK, PPCVSX): New. (powerpc_opcodes): Add opcodes "lxvd2x", "lxvd2ux", "stxvd2x", "stxvd2ux", "xxmrghd", "xxmrgld", "xxpermdi", "xvmovdp", "xvcpsgndp". --- gas/ChangeLog | 8 +++ gas/config/tc-ppc.c | 27 ++++++-- gas/doc/as.texinfo | 2 +- gas/doc/c-ppc.texi | 6 ++ gas/testsuite/ChangeLog | 6 ++ gas/testsuite/gas/ppc/power7.d | 57 ++++++++++++++++ gas/testsuite/gas/ppc/power7.s | 58 +++++++++++++++++ gas/testsuite/gas/ppc/ppc.exp | 1 + include/opcode/ChangeLog | 4 ++ include/opcode/ppc.h | 7 ++ opcodes/ChangeLog | 18 ++++++ opcodes/ppc-dis.c | 16 ++++- opcodes/ppc-opc.c | 144 +++++++++++++++++++++++++++++++++++++++++ 13 files changed, 347 insertions(+), 7 deletions(-) create mode 100644 gas/testsuite/gas/ppc/power7.d create mode 100644 gas/testsuite/gas/ppc/power7.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 2fe19f2..c2bb544 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2008-08-01 Peter Bergner + + * config/tc-ppc.c (parse_cpu): Rename altivec_or_spe to retain_flags. + Handle -mvsx and -mpower7. + (md_show_usage): Document -mpower7 and -mvsx. + * doc/as.texinfo (Target PowerPC): Document -mvsx. + * doc/c-ppc.texi (PowerPC-Opts): Document -mvsx and -mpower7. + 2008-07-31 Peter Bergner * config/tc-ppc.c (parse_cpu) : Accept Altivec instructions. diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index bded5f3..76a9e8e 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -825,7 +825,8 @@ const size_t md_longopts_size = sizeof (md_longopts); static int parse_cpu (const char *arg) { - ppc_cpu_t altivec_or_spe = ppc_cpu & (PPC_OPCODE_ALTIVEC | PPC_OPCODE_SPE); + ppc_cpu_t retain_flags = + ppc_cpu & (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX | PPC_OPCODE_SPE); /* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2 (RIOS2). */ @@ -873,7 +874,14 @@ parse_cpu (const char *arg) if (ppc_cpu == 0) ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC; - altivec_or_spe |= PPC_OPCODE_ALTIVEC; + retain_flags |= PPC_OPCODE_ALTIVEC; + } + else if (strcmp (arg, "vsx") == 0) + { + if (ppc_cpu == 0) + ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC; + + retain_flags |= PPC_OPCODE_VSX; } else if (strcmp (arg, "e500") == 0 || strcmp (arg, "e500x2") == 0) { @@ -893,7 +901,7 @@ parse_cpu (const char *arg) if (ppc_cpu == 0) ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_EFS; - altivec_or_spe |= PPC_OPCODE_SPE; + retain_flags |= PPC_OPCODE_SPE; } /* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC 620. */ @@ -935,6 +943,13 @@ parse_cpu (const char *arg) | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC); } + else if (strcmp (arg, "power7") == 0) + { + ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC + | PPC_OPCODE_64 | PPC_OPCODE_POWER4 + | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 + | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX); + } else if (strcmp (arg, "cell") == 0) { ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC @@ -952,8 +967,8 @@ parse_cpu (const char *arg) else return 0; - /* Make sure the the Altivec and SPE bits are not lost. */ - ppc_cpu |= altivec_or_spe; + /* Make sure the the Altivec, VSX and SPE bits are not lost. */ + ppc_cpu |= retain_flags; return 1; } @@ -1139,11 +1154,13 @@ PowerPC options:\n\ -mpower4 generate code for Power4 architecture\n\ -mpower5 generate code for Power5 architecture\n\ -mpower6 generate code for Power6 architecture\n\ +-mpower7 generate code for Power7 architecture\n\ -mcell generate code for Cell Broadband Engine architecture\n\ -mcom generate code Power/PowerPC common instructions\n\ -many generate code for any architecture (PWR/PWRX/PPC)\n")); fprintf (stream, _("\ -maltivec generate code for AltiVec\n\ +-mvsx generate code for Vector-Scalar (VSX) instructions\n\ -me300 generate code for PowerPC e300 family\n\ -me500, -me500x2 generate code for Motorola e500 core complex\n\ -me500mc, generate code for Freescale e500mc core complex\n\ diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index 635b707..2a373da 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -409,7 +409,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}. [@b{-mpwrx}|@b{-mpwr2}|@b{-mpwr}|@b{-m601}|@b{-mppc}|@b{-mppc32}|@b{-m603}|@b{-m604}| @b{-m403}|@b{-m405}|@b{-mppc64}|@b{-m620}|@b{-mppc64bridge}|@b{-mbooke}| @b{-mbooke32}|@b{-mbooke64}] - [@b{-mcom}|@b{-many}|@b{-maltivec}] [@b{-memb}] + [@b{-mcom}|@b{-many}|@b{-maltivec}|@b{-mvsx}] [@b{-memb}] [@b{-mregnames}|@b{-mno-regnames}] [@b{-mrelocatable}|@b{-mrelocatable-lib}] [@b{-mlittle}|@b{-mlittle-endian}|@b{-mbig}|@b{-mbig-endian}] diff --git a/gas/doc/c-ppc.texi b/gas/doc/c-ppc.texi index c71ace9..bc65685 100644 --- a/gas/doc/c-ppc.texi +++ b/gas/doc/c-ppc.texi @@ -82,6 +82,9 @@ Generate code for PowerPC e300 family. @item -maltivec Generate code for processors with AltiVec instructions. +@item -mvsx +Generate code for processors with Vector-Scalar (VSX) instructions. + @item -mpower4 Generate code for Power4 architecture. @@ -91,6 +94,9 @@ Generate code for Power5 architecture. @item -mpower6 Generate code for Power6 architecture. +@item -mpower7 +Generate code for Power7 architecture. + @item -mcell Generate code for Cell Broadband Engine architecture. diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 1ea3df5..7516f50 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-08-01 Peter Bergner + + * gas/ppc/power7.d: New. + * gas/ppc/power7.s: Likewise. + * gas/ppc/ppc.exp: Run power7 test. + 2008-08-01 H.J. Lu * gas/cfi/cfi-i386.s: Remove tests for AVX register maps. diff --git a/gas/testsuite/gas/ppc/power7.d b/gas/testsuite/gas/ppc/power7.d new file mode 100644 index 0000000..0401343 --- /dev/null +++ b/gas/testsuite/gas/ppc/power7.d @@ -0,0 +1,57 @@ +#as: -a32 -mpower7 +#objdump: -dr -Mpower7 +#name: POWER7 tests (includes DFP, Altivec and VSX) + +.*: +file format elf32-powerpc.* + +Disassembly of section \.text: + +0+00 : + 0: 7c 64 2e 98 lxvd2x vs3,r4,r5 + 4: 7c 64 2e d8 lxvd2ux vs3,r4,r5 + 8: 7d 64 2e 99 lxvd2x vs43,r4,r5 + c: 7d 64 2e d9 lxvd2ux vs43,r4,r5 + 10: 7c 64 2f 98 stxvd2x vs3,r4,r5 + 14: 7c 64 2f d8 stxvd2ux vs3,r4,r5 + 18: 7d 64 2f 99 stxvd2x vs43,r4,r5 + 1c: 7d 64 2f d9 stxvd2ux vs43,r4,r5 + 20: f0 64 28 50 xxmrghd vs3,vs4,vs5 + 24: f1 6c 68 57 xxmrghd vs43,vs44,vs45 + 28: f0 64 2b 50 xxmrgld vs3,vs4,vs5 + 2c: f1 6c 6b 57 xxmrgld vs43,vs44,vs45 + 30: f0 64 28 50 xxmrghd vs3,vs4,vs5 + 34: f1 6c 68 57 xxmrghd vs43,vs44,vs45 + 38: f0 64 2b 50 xxmrgld vs3,vs4,vs5 + 3c: f1 6c 6b 57 xxmrgld vs43,vs44,vs45 + 40: f0 64 29 50 xxpermdi vs3,vs4,vs5,1 + 44: f1 6c 69 57 xxpermdi vs43,vs44,vs45,1 + 48: f0 64 2a 50 xxpermdi vs3,vs4,vs5,2 + 4c: f1 6c 6a 57 xxpermdi vs43,vs44,vs45,2 + 50: f0 64 27 80 xvmovdp vs3,vs4 + 54: f1 6c 67 87 xvmovdp vs43,vs44 + 58: f0 64 27 80 xvmovdp vs3,vs4 + 5c: f1 6c 67 87 xvmovdp vs43,vs44 + 60: f0 64 2f 80 xvcpsgndp vs3,vs4,vs5 + 64: f1 6c 6f 87 xvcpsgndp vs43,vs44,vs45 + 68: 4c 00 03 24 doze + 6c: 4c 00 03 64 nap + 70: 4c 00 03 a4 sleep + 74: 4c 00 03 e4 rvwinkle + 78: 7c 83 01 34 prtyw r3,r4 + 7c: 7d cd 01 74 prtyd r13,r14 + 80: 7d 5c 02 a6 mfcfar r10 + 84: 7d 7c 03 a6 mtcfar r11 + 88: 7c 83 2b f8 cmpb r3,r4,r5 + 8c: 7c c0 3c be mffgpr f6,r7 + 90: 7d 00 4d be mftgpr r8,f9 + 94: 7d 4b 66 2a lwzcix r10,r11,r12 + 98: 7d ae 7e 2e lfdpx f13,r14,r15 + 9c: ee 11 90 04 dadd f16,f17,f18 + a0: fe 96 c0 04 daddq f20,f22,f24 + a4: 7c 60 06 6c dss 3 + a8: 7e 00 06 6c dssall + ac: 7c 25 22 ac dst r5,r4,1 + b0: 7e 08 3a ac dstt r8,r7,0 + b4: 7c 65 32 ec dstst r5,r6,3 + b8: 7e 44 2a ec dststt r4,r5,2 + bc: 4e 80 00 20 blr diff --git a/gas/testsuite/gas/ppc/power7.s b/gas/testsuite/gas/ppc/power7.s new file mode 100644 index 0000000..56fe0dc --- /dev/null +++ b/gas/testsuite/gas/ppc/power7.s @@ -0,0 +1,58 @@ + .file "power7.c" + .section ".text" + .align 2 + .p2align 4,,15 + .globl power7 + .type power7, @function +power7: + lxvd2x 3,4,5 + lxvd2ux 3,4,5 + lxvd2x 43,4,5 + lxvd2ux 43,4,5 + stxvd2x 3,4,5 + stxvd2ux 3,4,5 + stxvd2x 43,4,5 + stxvd2ux 43,4,5 + xxmrghd 3,4,5 + xxmrghd 43,44,45 + xxmrgld 3,4,5 + xxmrgld 43,44,45 + xxpermdi 3,4,5,0 + xxpermdi 43,44,45,0 + xxpermdi 3,4,5,3 + xxpermdi 43,44,45,3 + xxpermdi 3,4,5,1 + xxpermdi 43,44,45,1 + xxpermdi 3,4,5,2 + xxpermdi 43,44,45,2 + xvmovdp 3,4 + xvmovdp 43,44 + xvcpsgndp 3,4,4 + xvcpsgndp 43,44,44 + xvcpsgndp 3,4,5 + xvcpsgndp 43,44,45 + doze + nap + sleep + rvwinkle + prtyw 3,4 + prtyd 13,14 + mfcfar 10 + mtcfar 11 + cmpb 3,4,5 + mffgpr 6,7 + mftgpr 8,9 + lwzcix 10,11,12 + lfdpx 13,14,15 + dadd 16,17,18 + daddq 20,22,24 + dss 3 + dssall + dst 5,4,1 + dstt 8,7,0 + dstst 5,6,3 + dststt 4,5,2 + blr + .size power7,.-power7 + .ident "GCC: (GNU) 4.1.2 20070115 (prerelease) (SUSE Linux)" + .section .note.GNU-stack,"",@progbits diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp index 595e79c..90a5cff 100644 --- a/gas/testsuite/gas/ppc/ppc.exp +++ b/gas/testsuite/gas/ppc/ppc.exp @@ -46,5 +46,6 @@ if { [istarget powerpc*-*-*] } then { run_dump_test "e500mc" run_dump_test "cell" run_dump_test "power6" + run_dump_test "power7" } } diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 18aee1f..467cc5b 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2008-08-01 Peter Bergner + + * ppc.h (PPC_OPCODE_VSX, PPC_OPERAND_VSR): New. + 2008-07-30 Michael J. Eager * ppc.h (PPC_OPCODE_405): Define. diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h index a6b368a..0296b59 100644 --- a/include/opcode/ppc.h +++ b/include/opcode/ppc.h @@ -157,6 +157,9 @@ extern const int powerpc_num_opcodes; /* Opcode is supported by PowerPC 405 processor. */ #define PPC_OPCODE_405 0x40000000 +/* Opcode is supported by Vector-Scalar (VSX) Unit */ +#define PPC_OPCODE_VSX 0x80000000 + /* A macro to extract the major opcode from an instruction. */ #define PPC_OP(i) (((i) >> 26) & 0x3f) @@ -312,6 +315,10 @@ extern const unsigned int num_powerpc_operands; #define PPC_OPERAND_FSL (0x20000) #define PPC_OPERAND_FCR (0x40000) #define PPC_OPERAND_UDI (0x80000) + +/* This operand names a vector-scalar unit register. The disassembler + prints these with a leading 'vs'. */ +#define PPC_OPERAND_VSR (0x100000) /* The POWER and PowerPC assemblers use a few macros. We keep them with the operands table for simplicity. The macro table is an diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 1560fa9..4f5b607 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,21 @@ +2008-08-01 Peter Bergner + + * ppc-dis.c (powerpc_init_dialect): Handle power7 and vsx options. + (print_insn_powerpc): Prepend 'vs' when printing VSX registers. + (print_ppc_disassembler_options): Document -Mpower7 and -Mvsx. + * ppc-opc.c (insert_xt6): New static function. + (extract_xt6): Likewise. + (insert_xa6): Likewise. + (extract_xa6: Likewise. + (insert_xb6): Likewise. + (extract_xb6): Likewise. + (insert_xb6s): Likewise. + (extract_xb6s): Likewise. + (XS6, XT6, XA6, XB6, XB6S, DM, XX3, XX3DM, XX1_MASK, XX3_MASK, + XX3DM_MASK, PPCVSX): New. + (powerpc_opcodes): Add opcodes "lxvd2x", "lxvd2ux", "stxvd2x", + "stxvd2ux", "xxmrghd", "xxmrgld", "xxpermdi", "xvmovdp", "xvcpsgndp". + 2008-08-01 Pedro Alves * Makefile.am ($(srcdir)/ia64-asmtab.c): Remove line continuation. diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c index 7d4f9e1..bde4c49 100644 --- a/opcodes/ppc-dis.c +++ b/opcodes/ppc-dis.c @@ -107,7 +107,17 @@ powerpc_init_dialect (struct disassemble_info *info) if (info->disassembler_options && strstr (info->disassembler_options, "power6") != NULL) - dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC; + dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 + | PPC_OPCODE_ALTIVEC; + + if (info->disassembler_options + && strstr (info->disassembler_options, "power7") != NULL) + dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 + | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX; + + if (info->disassembler_options + && strstr (info->disassembler_options, "vsx") != NULL) + dialect |= PPC_OPCODE_VSX; if (info->disassembler_options && strstr (info->disassembler_options, "any") != NULL) @@ -321,6 +331,8 @@ print_insn_powerpc (bfd_vma memaddr, (*info->fprintf_func) (info->stream, "f%ld", value); else if ((operand->flags & PPC_OPERAND_VR) != 0) (*info->fprintf_func) (info->stream, "v%ld", value); + else if ((operand->flags & PPC_OPERAND_VSR) != 0) + (*info->fprintf_func) (info->stream, "vs%ld", value); else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) (*info->print_address_func) (memaddr + value, info); else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) @@ -401,6 +413,8 @@ the -M switch:\n"); fprintf (stream, " power4 Disassemble the Power4 instructions\n"); fprintf (stream, " power5 Disassemble the Power5 instructions\n"); fprintf (stream, " power6 Disassemble the Power6 instructions\n"); + fprintf (stream, " power7 Disassemble the Power7 instructions\n"); + fprintf (stream, " vsx Disassemble the Vector-Scalar (VSX) instructions\n"); fprintf (stream, " 32 Do not disassemble 64-bit instructions\n"); fprintf (stream, " 64 Allow disassembly of 64-bit instructions\n"); } diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c index 617d976..e0d833c 100644 --- a/opcodes/ppc-opc.c +++ b/opcodes/ppc-opc.c @@ -73,6 +73,14 @@ static unsigned long insert_sprg (unsigned long, long, ppc_cpu_t, const char **) static long extract_sprg (unsigned long, ppc_cpu_t, int *); static unsigned long insert_tbr (unsigned long, long, ppc_cpu_t, const char **); static long extract_tbr (unsigned long, ppc_cpu_t, int *); +static unsigned long insert_xt6 (unsigned long, long, ppc_cpu_t, const char **); +static long extract_xt6 (unsigned long, ppc_cpu_t, int *); +static unsigned long insert_xa6 (unsigned long, long, ppc_cpu_t, const char **); +static long extract_xa6 (unsigned long, ppc_cpu_t, int *); +static unsigned long insert_xb6 (unsigned long, long, ppc_cpu_t, const char **); +static long extract_xb6 (unsigned long, ppc_cpu_t, int *); +static unsigned long insert_xb6s (unsigned long, long, ppc_cpu_t, const char **); +static long extract_xb6s (unsigned long, ppc_cpu_t, int *); /* The operands table. @@ -600,6 +608,28 @@ const struct powerpc_operand powerpc_operands[] = #define URC URB + 1 { 0x1f, 6, 0, 0, PPC_OPERAND_UDI }, + /* The XT and XS fields in an XX1 or XX3 form instruction. This is split. */ +#define XS6 URC + 1 +#define XT6 XS6 + { 0x3f, -1, insert_xt6, extract_xt6, PPC_OPERAND_VSR }, + + /* The XA field in an XX3 form instruction. This is split. */ +#define XA6 XT6 + 1 + { 0x3f, -1, insert_xa6, extract_xa6, PPC_OPERAND_VSR }, + + /* The XB field in an XX3 form instruction. This is split. */ +#define XB6 XA6 + 1 + { 0x3f, -1, insert_xb6, extract_xb6, PPC_OPERAND_VSR }, + + /* The XB field in an XX3 form instruction when it must be the same as + the XA field in the instruction. This is used in extended mnemonics + like xvmovdp. This is split. */ +#define XB6S XB6 + 1 + { 0x3f, -1, insert_xb6s, extract_xb6s, PPC_OPERAND_FAKE }, + + /* The DM field in an XX3 form instruction. */ +#define DM XB6S + 1 + { 0x3, 8, NULL, NULL, 0 }, }; const unsigned int num_powerpc_operands = (sizeof (powerpc_operands) @@ -1292,6 +1322,89 @@ extract_tbr (unsigned long insn, ret = 0; return ret; } + +/* The XT and XS fields in an XX1 or XX3 form instruction. This is split. */ + +static unsigned long +insert_xt6 (unsigned long insn, + long value, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0x1f) << 21) | ((value & 0x20) >> 5); +} + +static long +extract_xt6 (unsigned long insn, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + int *invalid ATTRIBUTE_UNUSED) +{ + return ((insn << 5) & 0x20) | ((insn >> 21) & 0x1f); +} + +/* The XA field in an XX3 form instruction. This is split. */ + +static unsigned long +insert_xa6 (unsigned long insn, + long value, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0x1f) << 16) | ((value & 0x20) >> 3); +} + +static long +extract_xa6 (unsigned long insn, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + int *invalid ATTRIBUTE_UNUSED) +{ + return ((insn << 3) & 0x20) | ((insn >> 16) & 0x1f); +} + +/* The XB field in an XX3 form instruction. This is split. */ + +static unsigned long +insert_xb6 (unsigned long insn, + long value, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4); +} + +static long +extract_xb6 (unsigned long insn, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + int *invalid ATTRIBUTE_UNUSED) +{ + return ((insn << 4) & 0x20) | ((insn >> 11) & 0x1f); +} + +/* The XB field in an XX3 form instruction when it must be the same as + the XA field in the instruction. This is used for extended + mnemonics like xvmovdp. This operand is marked FAKE. The insertion + function just copies the XA field into the XB field, and the + extraction function just checks that the fields are the same. */ + +static unsigned long +insert_xb6s (unsigned long insn, + long value ATTRIBUTE_UNUSED, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + return insn | (((insn >> 16) & 0x1f) << 11) | (((insn >> 2) & 0x1) << 1); +} + +static long +extract_xb6s (unsigned long insn, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + int *invalid) +{ + if ((((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f)) + || (((insn >> 2) & 0x1) != ((insn >> 1) & 0x1))) + *invalid = 1; + return 0; +} /* Macros used to form opcodes. */ @@ -1437,6 +1550,12 @@ extract_tbr (unsigned long insn, /* An X form instruction. */ #define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1)) +/* An XX3 form instruction. */ +#define XX3(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0xff) << 3)) + +#define XX3DM(op, xop, dm) (XX3 (op, ((unsigned long)(xop) & 0x1f)) \ + | ((((unsigned long)(dm)) & 0x3) << 8)) + /* A Z form instruction. */ #define Z(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1)) @@ -1449,6 +1568,15 @@ extract_tbr (unsigned long insn, /* The mask for an X form instruction. */ #define X_MASK XRC (0x3f, 0x3ff, 1) +/* The mask for an XX1 form instruction. */ +#define XX1_MASK X (0x3f, 0x3ff) + +/* The mask for an XX3 form instruction. */ +#define XX3_MASK XX3 (0x3f, 0xff) + +/* The mask for an XX3 form instruction with the DM bits specified. */ +#define XX3DM_MASK (XX3 (0x3f, 0x1f) | (1 << 10)) + /* The mask for a Z form instruction. */ #define Z_MASK ZRC (0x3f, 0x1ff, 1) #define Z2_MASK ZRC (0x3f, 0xff, 1) @@ -1701,6 +1829,7 @@ extract_tbr (unsigned long insn, #define PPC860 PPC #define PPCPS PPC_OPCODE_PPCPS #define PPCVEC PPC_OPCODE_ALTIVEC +#define PPCVSX PPC_OPCODE_VSX #define POWER PPC_OPCODE_POWER #define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2 #define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2 @@ -4441,6 +4570,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { {"divo.", XO(31,331,1,1), XO_MASK, M601, {RT, RA, RB}}, {"lduxe", X(31,831), X_MASK, BOOKE64, {RT, RA0, RB}}, +{"lxvd2x", X(31,844), XX1_MASK, PPCVSX, {XT6, RA, RB}}, + {"slbmfev", X(31,851), XRA_MASK, PPC64, {RT, RB}}, {"lbzcix", X(31,853), X_MASK, POWER6, {RT, RA0, RB}}, @@ -4456,6 +4587,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { {"divso", XO(31,363,1,0), XO_MASK, M601, {RT, RA, RB}}, {"divso.", XO(31,363,1,1), XO_MASK, M601, {RT, RA, RB}}, +{"lxvd2ux", X(31,876), XX1_MASK, PPCVSX, {XT6, RA, RB}}, + {"ldcix", X(31,885), X_MASK, POWER6, {RT, RA0, RB}}, {"stvlxl", X(31,903), X_MASK, CELL, {VS, RA0, RB}}, @@ -4526,6 +4659,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { {"divwuo", XO(31,459,1,0), XO_MASK, PPC, {RT, RA, RB}}, {"divwuo.", XO(31,459,1,1), XO_MASK, PPC, {RT, RA, RB}}, +{"stxvd2x", X(31,972), XX1_MASK, PPCVSX, {XS6, RA, RB}}, + {"tlbwehi", XTLB(31,978,0), XTLB_MASK, PPC403, {RT, RA}}, {"tlbwelo", XTLB(31,978,1), XTLB_MASK, PPC403, {RT, RA}}, {"tlbwe", X(31,978), X_MASK, PPC403|BOOKE, {RSO, RAOPT, SHO}}, @@ -4559,6 +4694,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { {"divwo", XO(31,491,1,0), XO_MASK, PPC, {RT, RA, RB}}, {"divwo.", XO(31,491,1,1), XO_MASK, PPC, {RT, RA, RB}}, +{"stxvd2ux", X(31,1004), XX1_MASK, PPCVSX, {XS6, RA, RB}}, + {"tlbli", X(31,1010), XRTRA_MASK, PPC, {RB}}, {"stdcix", X(31,1013), X_MASK, POWER6, {RS, RA0, RB}}, @@ -4770,6 +4907,13 @@ const struct powerpc_opcode powerpc_opcodes[] = { {"stfq", OP(60), OP_MASK, POWER2, {FRS, D, RA}}, {"psq_st", OP(60), OP_MASK, PPCPS, {FRS,PSD,RA,PSW,PSQ}}, + +{"xxmrghd", XX3(60,10), XX3_MASK, PPCVSX, {XT6, XA6, XB6}}, +{"xxmrgld", XX3(60,10)|(3<<8), XX3_MASK, PPCVSX, {XT6, XA6, XB6}}, +{"xxpermdi", XX3(60,10), XX3DM_MASK, PPCVSX, {XT6, XA6, XB6, DM}}, +{"xvmovdp", XX3(60,240), XX3_MASK, PPCVSX, {XT6, XA6, XB6S}}, +{"xvcpsgndp", XX3(60,240), XX3_MASK, PPCVSX, {XT6, XA6, XB6}}, + {"psq_stu", OP(61), OP_MASK, PPCPS, {FRS,PSD,RA,PSW,PSQ}}, {"stfqu", OP(61), OP_MASK, POWER2, {FRS, D, RA}}, -- 2.7.4