/* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
- Copyright (C) 1994-2016 Free Software Foundation, Inc.
+ Copyright (C) 1994-2018 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
/* Warn on emitting data to code sections. */
int warn_476;
-unsigned long last_insn;
+uint64_t last_insn;
segT last_seg;
subsegT last_subseg;
\f
struct pd_reg
{
const char *name;
- int value;
+ unsigned short value;
+ unsigned short flags;
};
/* List of registers that are pre-defined:
There are individual registers as well:
sp or r.sp has the value 1
rtoc or r.toc has the value 2
- fpscr has the value 0
xer has the value 1
lr has the value 8
ctr has the value 9
- pmr has the value 0
dar has the value 19
dsisr has the value 18
dec has the value 22
static const struct pd_reg pre_defined_registers[] =
{
- { "cr.0", 0 }, /* Condition Registers */
- { "cr.1", 1 },
- { "cr.2", 2 },
- { "cr.3", 3 },
- { "cr.4", 4 },
- { "cr.5", 5 },
- { "cr.6", 6 },
- { "cr.7", 7 },
-
- { "cr0", 0 },
- { "cr1", 1 },
- { "cr2", 2 },
- { "cr3", 3 },
- { "cr4", 4 },
- { "cr5", 5 },
- { "cr6", 6 },
- { "cr7", 7 },
-
- { "ctr", 9 },
-
- { "dar", 19 }, /* Data Access Register */
- { "dec", 22 }, /* Decrementer */
- { "dsisr", 18 }, /* Data Storage Interrupt Status Register */
-
- { "f.0", 0 }, /* Floating point registers */
- { "f.1", 1 },
- { "f.10", 10 },
- { "f.11", 11 },
- { "f.12", 12 },
- { "f.13", 13 },
- { "f.14", 14 },
- { "f.15", 15 },
- { "f.16", 16 },
- { "f.17", 17 },
- { "f.18", 18 },
- { "f.19", 19 },
- { "f.2", 2 },
- { "f.20", 20 },
- { "f.21", 21 },
- { "f.22", 22 },
- { "f.23", 23 },
- { "f.24", 24 },
- { "f.25", 25 },
- { "f.26", 26 },
- { "f.27", 27 },
- { "f.28", 28 },
- { "f.29", 29 },
- { "f.3", 3 },
- { "f.30", 30 },
- { "f.31", 31 },
-
- { "f.32", 32 }, /* Extended floating point scalar registers (ISA 2.06). */
- { "f.33", 33 },
- { "f.34", 34 },
- { "f.35", 35 },
- { "f.36", 36 },
- { "f.37", 37 },
- { "f.38", 38 },
- { "f.39", 39 },
- { "f.4", 4 },
- { "f.40", 40 },
- { "f.41", 41 },
- { "f.42", 42 },
- { "f.43", 43 },
- { "f.44", 44 },
- { "f.45", 45 },
- { "f.46", 46 },
- { "f.47", 47 },
- { "f.48", 48 },
- { "f.49", 49 },
- { "f.5", 5 },
- { "f.50", 50 },
- { "f.51", 51 },
- { "f.52", 52 },
- { "f.53", 53 },
- { "f.54", 54 },
- { "f.55", 55 },
- { "f.56", 56 },
- { "f.57", 57 },
- { "f.58", 58 },
- { "f.59", 59 },
- { "f.6", 6 },
- { "f.60", 60 },
- { "f.61", 61 },
- { "f.62", 62 },
- { "f.63", 63 },
- { "f.7", 7 },
- { "f.8", 8 },
- { "f.9", 9 },
-
- { "f0", 0 },
- { "f1", 1 },
- { "f10", 10 },
- { "f11", 11 },
- { "f12", 12 },
- { "f13", 13 },
- { "f14", 14 },
- { "f15", 15 },
- { "f16", 16 },
- { "f17", 17 },
- { "f18", 18 },
- { "f19", 19 },
- { "f2", 2 },
- { "f20", 20 },
- { "f21", 21 },
- { "f22", 22 },
- { "f23", 23 },
- { "f24", 24 },
- { "f25", 25 },
- { "f26", 26 },
- { "f27", 27 },
- { "f28", 28 },
- { "f29", 29 },
- { "f3", 3 },
- { "f30", 30 },
- { "f31", 31 },
-
- { "f32", 32 }, /* Extended floating point scalar registers (ISA 2.06). */
- { "f33", 33 },
- { "f34", 34 },
- { "f35", 35 },
- { "f36", 36 },
- { "f37", 37 },
- { "f38", 38 },
- { "f39", 39 },
- { "f4", 4 },
- { "f40", 40 },
- { "f41", 41 },
- { "f42", 42 },
- { "f43", 43 },
- { "f44", 44 },
- { "f45", 45 },
- { "f46", 46 },
- { "f47", 47 },
- { "f48", 48 },
- { "f49", 49 },
- { "f5", 5 },
- { "f50", 50 },
- { "f51", 51 },
- { "f52", 52 },
- { "f53", 53 },
- { "f54", 54 },
- { "f55", 55 },
- { "f56", 56 },
- { "f57", 57 },
- { "f58", 58 },
- { "f59", 59 },
- { "f6", 6 },
- { "f60", 60 },
- { "f61", 61 },
- { "f62", 62 },
- { "f63", 63 },
- { "f7", 7 },
- { "f8", 8 },
- { "f9", 9 },
-
- { "fpscr", 0 },
+ /* Condition Registers */
+ { "cr.0", 0, PPC_OPERAND_CR_REG },
+ { "cr.1", 1, PPC_OPERAND_CR_REG },
+ { "cr.2", 2, PPC_OPERAND_CR_REG },
+ { "cr.3", 3, PPC_OPERAND_CR_REG },
+ { "cr.4", 4, PPC_OPERAND_CR_REG },
+ { "cr.5", 5, PPC_OPERAND_CR_REG },
+ { "cr.6", 6, PPC_OPERAND_CR_REG },
+ { "cr.7", 7, PPC_OPERAND_CR_REG },
+
+ { "cr0", 0, PPC_OPERAND_CR_REG },
+ { "cr1", 1, PPC_OPERAND_CR_REG },
+ { "cr2", 2, PPC_OPERAND_CR_REG },
+ { "cr3", 3, PPC_OPERAND_CR_REG },
+ { "cr4", 4, PPC_OPERAND_CR_REG },
+ { "cr5", 5, PPC_OPERAND_CR_REG },
+ { "cr6", 6, PPC_OPERAND_CR_REG },
+ { "cr7", 7, PPC_OPERAND_CR_REG },
+
+ { "ctr", 9, PPC_OPERAND_SPR },
+ { "dar", 19, PPC_OPERAND_SPR },
+ { "dec", 22, PPC_OPERAND_SPR },
+ { "dsisr", 18, PPC_OPERAND_SPR },
+
+ /* Floating point registers */
+ { "f.0", 0, PPC_OPERAND_FPR },
+ { "f.1", 1, PPC_OPERAND_FPR },
+ { "f.10", 10, PPC_OPERAND_FPR },
+ { "f.11", 11, PPC_OPERAND_FPR },
+ { "f.12", 12, PPC_OPERAND_FPR },
+ { "f.13", 13, PPC_OPERAND_FPR },
+ { "f.14", 14, PPC_OPERAND_FPR },
+ { "f.15", 15, PPC_OPERAND_FPR },
+ { "f.16", 16, PPC_OPERAND_FPR },
+ { "f.17", 17, PPC_OPERAND_FPR },
+ { "f.18", 18, PPC_OPERAND_FPR },
+ { "f.19", 19, PPC_OPERAND_FPR },
+ { "f.2", 2, PPC_OPERAND_FPR },
+ { "f.20", 20, PPC_OPERAND_FPR },
+ { "f.21", 21, PPC_OPERAND_FPR },
+ { "f.22", 22, PPC_OPERAND_FPR },
+ { "f.23", 23, PPC_OPERAND_FPR },
+ { "f.24", 24, PPC_OPERAND_FPR },
+ { "f.25", 25, PPC_OPERAND_FPR },
+ { "f.26", 26, PPC_OPERAND_FPR },
+ { "f.27", 27, PPC_OPERAND_FPR },
+ { "f.28", 28, PPC_OPERAND_FPR },
+ { "f.29", 29, PPC_OPERAND_FPR },
+ { "f.3", 3, PPC_OPERAND_FPR },
+ { "f.30", 30, PPC_OPERAND_FPR },
+ { "f.31", 31, PPC_OPERAND_FPR },
+ { "f.32", 32, PPC_OPERAND_VSR },
+ { "f.33", 33, PPC_OPERAND_VSR },
+ { "f.34", 34, PPC_OPERAND_VSR },
+ { "f.35", 35, PPC_OPERAND_VSR },
+ { "f.36", 36, PPC_OPERAND_VSR },
+ { "f.37", 37, PPC_OPERAND_VSR },
+ { "f.38", 38, PPC_OPERAND_VSR },
+ { "f.39", 39, PPC_OPERAND_VSR },
+ { "f.4", 4, PPC_OPERAND_FPR },
+ { "f.40", 40, PPC_OPERAND_VSR },
+ { "f.41", 41, PPC_OPERAND_VSR },
+ { "f.42", 42, PPC_OPERAND_VSR },
+ { "f.43", 43, PPC_OPERAND_VSR },
+ { "f.44", 44, PPC_OPERAND_VSR },
+ { "f.45", 45, PPC_OPERAND_VSR },
+ { "f.46", 46, PPC_OPERAND_VSR },
+ { "f.47", 47, PPC_OPERAND_VSR },
+ { "f.48", 48, PPC_OPERAND_VSR },
+ { "f.49", 49, PPC_OPERAND_VSR },
+ { "f.5", 5, PPC_OPERAND_FPR },
+ { "f.50", 50, PPC_OPERAND_VSR },
+ { "f.51", 51, PPC_OPERAND_VSR },
+ { "f.52", 52, PPC_OPERAND_VSR },
+ { "f.53", 53, PPC_OPERAND_VSR },
+ { "f.54", 54, PPC_OPERAND_VSR },
+ { "f.55", 55, PPC_OPERAND_VSR },
+ { "f.56", 56, PPC_OPERAND_VSR },
+ { "f.57", 57, PPC_OPERAND_VSR },
+ { "f.58", 58, PPC_OPERAND_VSR },
+ { "f.59", 59, PPC_OPERAND_VSR },
+ { "f.6", 6, PPC_OPERAND_FPR },
+ { "f.60", 60, PPC_OPERAND_VSR },
+ { "f.61", 61, PPC_OPERAND_VSR },
+ { "f.62", 62, PPC_OPERAND_VSR },
+ { "f.63", 63, PPC_OPERAND_VSR },
+ { "f.7", 7, PPC_OPERAND_FPR },
+ { "f.8", 8, PPC_OPERAND_FPR },
+ { "f.9", 9, PPC_OPERAND_FPR },
+
+ { "f0", 0, PPC_OPERAND_FPR },
+ { "f1", 1, PPC_OPERAND_FPR },
+ { "f10", 10, PPC_OPERAND_FPR },
+ { "f11", 11, PPC_OPERAND_FPR },
+ { "f12", 12, PPC_OPERAND_FPR },
+ { "f13", 13, PPC_OPERAND_FPR },
+ { "f14", 14, PPC_OPERAND_FPR },
+ { "f15", 15, PPC_OPERAND_FPR },
+ { "f16", 16, PPC_OPERAND_FPR },
+ { "f17", 17, PPC_OPERAND_FPR },
+ { "f18", 18, PPC_OPERAND_FPR },
+ { "f19", 19, PPC_OPERAND_FPR },
+ { "f2", 2, PPC_OPERAND_FPR },
+ { "f20", 20, PPC_OPERAND_FPR },
+ { "f21", 21, PPC_OPERAND_FPR },
+ { "f22", 22, PPC_OPERAND_FPR },
+ { "f23", 23, PPC_OPERAND_FPR },
+ { "f24", 24, PPC_OPERAND_FPR },
+ { "f25", 25, PPC_OPERAND_FPR },
+ { "f26", 26, PPC_OPERAND_FPR },
+ { "f27", 27, PPC_OPERAND_FPR },
+ { "f28", 28, PPC_OPERAND_FPR },
+ { "f29", 29, PPC_OPERAND_FPR },
+ { "f3", 3, PPC_OPERAND_FPR },
+ { "f30", 30, PPC_OPERAND_FPR },
+ { "f31", 31, PPC_OPERAND_FPR },
+ { "f32", 32, PPC_OPERAND_VSR },
+ { "f33", 33, PPC_OPERAND_VSR },
+ { "f34", 34, PPC_OPERAND_VSR },
+ { "f35", 35, PPC_OPERAND_VSR },
+ { "f36", 36, PPC_OPERAND_VSR },
+ { "f37", 37, PPC_OPERAND_VSR },
+ { "f38", 38, PPC_OPERAND_VSR },
+ { "f39", 39, PPC_OPERAND_VSR },
+ { "f4", 4, PPC_OPERAND_FPR },
+ { "f40", 40, PPC_OPERAND_VSR },
+ { "f41", 41, PPC_OPERAND_VSR },
+ { "f42", 42, PPC_OPERAND_VSR },
+ { "f43", 43, PPC_OPERAND_VSR },
+ { "f44", 44, PPC_OPERAND_VSR },
+ { "f45", 45, PPC_OPERAND_VSR },
+ { "f46", 46, PPC_OPERAND_VSR },
+ { "f47", 47, PPC_OPERAND_VSR },
+ { "f48", 48, PPC_OPERAND_VSR },
+ { "f49", 49, PPC_OPERAND_VSR },
+ { "f5", 5, PPC_OPERAND_FPR },
+ { "f50", 50, PPC_OPERAND_VSR },
+ { "f51", 51, PPC_OPERAND_VSR },
+ { "f52", 52, PPC_OPERAND_VSR },
+ { "f53", 53, PPC_OPERAND_VSR },
+ { "f54", 54, PPC_OPERAND_VSR },
+ { "f55", 55, PPC_OPERAND_VSR },
+ { "f56", 56, PPC_OPERAND_VSR },
+ { "f57", 57, PPC_OPERAND_VSR },
+ { "f58", 58, PPC_OPERAND_VSR },
+ { "f59", 59, PPC_OPERAND_VSR },
+ { "f6", 6, PPC_OPERAND_FPR },
+ { "f60", 60, PPC_OPERAND_VSR },
+ { "f61", 61, PPC_OPERAND_VSR },
+ { "f62", 62, PPC_OPERAND_VSR },
+ { "f63", 63, PPC_OPERAND_VSR },
+ { "f7", 7, PPC_OPERAND_FPR },
+ { "f8", 8, PPC_OPERAND_FPR },
+ { "f9", 9, PPC_OPERAND_FPR },
/* Quantization registers used with pair single instructions. */
- { "gqr.0", 0 },
- { "gqr.1", 1 },
- { "gqr.2", 2 },
- { "gqr.3", 3 },
- { "gqr.4", 4 },
- { "gqr.5", 5 },
- { "gqr.6", 6 },
- { "gqr.7", 7 },
- { "gqr0", 0 },
- { "gqr1", 1 },
- { "gqr2", 2 },
- { "gqr3", 3 },
- { "gqr4", 4 },
- { "gqr5", 5 },
- { "gqr6", 6 },
- { "gqr7", 7 },
-
- { "lr", 8 }, /* Link Register */
-
- { "pmr", 0 },
-
- { "r.0", 0 }, /* General Purpose Registers */
- { "r.1", 1 },
- { "r.10", 10 },
- { "r.11", 11 },
- { "r.12", 12 },
- { "r.13", 13 },
- { "r.14", 14 },
- { "r.15", 15 },
- { "r.16", 16 },
- { "r.17", 17 },
- { "r.18", 18 },
- { "r.19", 19 },
- { "r.2", 2 },
- { "r.20", 20 },
- { "r.21", 21 },
- { "r.22", 22 },
- { "r.23", 23 },
- { "r.24", 24 },
- { "r.25", 25 },
- { "r.26", 26 },
- { "r.27", 27 },
- { "r.28", 28 },
- { "r.29", 29 },
- { "r.3", 3 },
- { "r.30", 30 },
- { "r.31", 31 },
- { "r.4", 4 },
- { "r.5", 5 },
- { "r.6", 6 },
- { "r.7", 7 },
- { "r.8", 8 },
- { "r.9", 9 },
-
- { "r.sp", 1 }, /* Stack Pointer */
-
- { "r.toc", 2 }, /* Pointer to the table of contents */
-
- { "r0", 0 }, /* More general purpose registers */
- { "r1", 1 },
- { "r10", 10 },
- { "r11", 11 },
- { "r12", 12 },
- { "r13", 13 },
- { "r14", 14 },
- { "r15", 15 },
- { "r16", 16 },
- { "r17", 17 },
- { "r18", 18 },
- { "r19", 19 },
- { "r2", 2 },
- { "r20", 20 },
- { "r21", 21 },
- { "r22", 22 },
- { "r23", 23 },
- { "r24", 24 },
- { "r25", 25 },
- { "r26", 26 },
- { "r27", 27 },
- { "r28", 28 },
- { "r29", 29 },
- { "r3", 3 },
- { "r30", 30 },
- { "r31", 31 },
- { "r4", 4 },
- { "r5", 5 },
- { "r6", 6 },
- { "r7", 7 },
- { "r8", 8 },
- { "r9", 9 },
-
- { "rtoc", 2 }, /* Table of contents */
-
- { "sdr1", 25 }, /* Storage Description Register 1 */
-
- { "sp", 1 },
-
- { "srr0", 26 }, /* Machine Status Save/Restore Register 0 */
- { "srr1", 27 }, /* Machine Status Save/Restore Register 1 */
-
- { "v.0", 0 }, /* Vector (Altivec/VMX) registers */
- { "v.1", 1 },
- { "v.10", 10 },
- { "v.11", 11 },
- { "v.12", 12 },
- { "v.13", 13 },
- { "v.14", 14 },
- { "v.15", 15 },
- { "v.16", 16 },
- { "v.17", 17 },
- { "v.18", 18 },
- { "v.19", 19 },
- { "v.2", 2 },
- { "v.20", 20 },
- { "v.21", 21 },
- { "v.22", 22 },
- { "v.23", 23 },
- { "v.24", 24 },
- { "v.25", 25 },
- { "v.26", 26 },
- { "v.27", 27 },
- { "v.28", 28 },
- { "v.29", 29 },
- { "v.3", 3 },
- { "v.30", 30 },
- { "v.31", 31 },
- { "v.4", 4 },
- { "v.5", 5 },
- { "v.6", 6 },
- { "v.7", 7 },
- { "v.8", 8 },
- { "v.9", 9 },
-
- { "v0", 0 },
- { "v1", 1 },
- { "v10", 10 },
- { "v11", 11 },
- { "v12", 12 },
- { "v13", 13 },
- { "v14", 14 },
- { "v15", 15 },
- { "v16", 16 },
- { "v17", 17 },
- { "v18", 18 },
- { "v19", 19 },
- { "v2", 2 },
- { "v20", 20 },
- { "v21", 21 },
- { "v22", 22 },
- { "v23", 23 },
- { "v24", 24 },
- { "v25", 25 },
- { "v26", 26 },
- { "v27", 27 },
- { "v28", 28 },
- { "v29", 29 },
- { "v3", 3 },
- { "v30", 30 },
- { "v31", 31 },
- { "v4", 4 },
- { "v5", 5 },
- { "v6", 6 },
- { "v7", 7 },
- { "v8", 8 },
- { "v9", 9 },
-
- { "vs.0", 0 }, /* Vector Scalar (VSX) registers (ISA 2.06). */
- { "vs.1", 1 },
- { "vs.10", 10 },
- { "vs.11", 11 },
- { "vs.12", 12 },
- { "vs.13", 13 },
- { "vs.14", 14 },
- { "vs.15", 15 },
- { "vs.16", 16 },
- { "vs.17", 17 },
- { "vs.18", 18 },
- { "vs.19", 19 },
- { "vs.2", 2 },
- { "vs.20", 20 },
- { "vs.21", 21 },
- { "vs.22", 22 },
- { "vs.23", 23 },
- { "vs.24", 24 },
- { "vs.25", 25 },
- { "vs.26", 26 },
- { "vs.27", 27 },
- { "vs.28", 28 },
- { "vs.29", 29 },
- { "vs.3", 3 },
- { "vs.30", 30 },
- { "vs.31", 31 },
- { "vs.32", 32 },
- { "vs.33", 33 },
- { "vs.34", 34 },
- { "vs.35", 35 },
- { "vs.36", 36 },
- { "vs.37", 37 },
- { "vs.38", 38 },
- { "vs.39", 39 },
- { "vs.4", 4 },
- { "vs.40", 40 },
- { "vs.41", 41 },
- { "vs.42", 42 },
- { "vs.43", 43 },
- { "vs.44", 44 },
- { "vs.45", 45 },
- { "vs.46", 46 },
- { "vs.47", 47 },
- { "vs.48", 48 },
- { "vs.49", 49 },
- { "vs.5", 5 },
- { "vs.50", 50 },
- { "vs.51", 51 },
- { "vs.52", 52 },
- { "vs.53", 53 },
- { "vs.54", 54 },
- { "vs.55", 55 },
- { "vs.56", 56 },
- { "vs.57", 57 },
- { "vs.58", 58 },
- { "vs.59", 59 },
- { "vs.6", 6 },
- { "vs.60", 60 },
- { "vs.61", 61 },
- { "vs.62", 62 },
- { "vs.63", 63 },
- { "vs.7", 7 },
- { "vs.8", 8 },
- { "vs.9", 9 },
-
- { "vs0", 0 },
- { "vs1", 1 },
- { "vs10", 10 },
- { "vs11", 11 },
- { "vs12", 12 },
- { "vs13", 13 },
- { "vs14", 14 },
- { "vs15", 15 },
- { "vs16", 16 },
- { "vs17", 17 },
- { "vs18", 18 },
- { "vs19", 19 },
- { "vs2", 2 },
- { "vs20", 20 },
- { "vs21", 21 },
- { "vs22", 22 },
- { "vs23", 23 },
- { "vs24", 24 },
- { "vs25", 25 },
- { "vs26", 26 },
- { "vs27", 27 },
- { "vs28", 28 },
- { "vs29", 29 },
- { "vs3", 3 },
- { "vs30", 30 },
- { "vs31", 31 },
- { "vs32", 32 },
- { "vs33", 33 },
- { "vs34", 34 },
- { "vs35", 35 },
- { "vs36", 36 },
- { "vs37", 37 },
- { "vs38", 38 },
- { "vs39", 39 },
- { "vs4", 4 },
- { "vs40", 40 },
- { "vs41", 41 },
- { "vs42", 42 },
- { "vs43", 43 },
- { "vs44", 44 },
- { "vs45", 45 },
- { "vs46", 46 },
- { "vs47", 47 },
- { "vs48", 48 },
- { "vs49", 49 },
- { "vs5", 5 },
- { "vs50", 50 },
- { "vs51", 51 },
- { "vs52", 52 },
- { "vs53", 53 },
- { "vs54", 54 },
- { "vs55", 55 },
- { "vs56", 56 },
- { "vs57", 57 },
- { "vs58", 58 },
- { "vs59", 59 },
- { "vs6", 6 },
- { "vs60", 60 },
- { "vs61", 61 },
- { "vs62", 62 },
- { "vs63", 63 },
- { "vs7", 7 },
- { "vs8", 8 },
- { "vs9", 9 },
-
- { "xer", 1 },
-
+ { "gqr.0", 0, PPC_OPERAND_GQR },
+ { "gqr.1", 1, PPC_OPERAND_GQR },
+ { "gqr.2", 2, PPC_OPERAND_GQR },
+ { "gqr.3", 3, PPC_OPERAND_GQR },
+ { "gqr.4", 4, PPC_OPERAND_GQR },
+ { "gqr.5", 5, PPC_OPERAND_GQR },
+ { "gqr.6", 6, PPC_OPERAND_GQR },
+ { "gqr.7", 7, PPC_OPERAND_GQR },
+ { "gqr0", 0, PPC_OPERAND_GQR },
+ { "gqr1", 1, PPC_OPERAND_GQR },
+ { "gqr2", 2, PPC_OPERAND_GQR },
+ { "gqr3", 3, PPC_OPERAND_GQR },
+ { "gqr4", 4, PPC_OPERAND_GQR },
+ { "gqr5", 5, PPC_OPERAND_GQR },
+ { "gqr6", 6, PPC_OPERAND_GQR },
+ { "gqr7", 7, PPC_OPERAND_GQR },
+
+ { "lr", 8, PPC_OPERAND_SPR },
+
+ /* General Purpose Registers */
+ { "r.0", 0, PPC_OPERAND_GPR },
+ { "r.1", 1, PPC_OPERAND_GPR },
+ { "r.10", 10, PPC_OPERAND_GPR },
+ { "r.11", 11, PPC_OPERAND_GPR },
+ { "r.12", 12, PPC_OPERAND_GPR },
+ { "r.13", 13, PPC_OPERAND_GPR },
+ { "r.14", 14, PPC_OPERAND_GPR },
+ { "r.15", 15, PPC_OPERAND_GPR },
+ { "r.16", 16, PPC_OPERAND_GPR },
+ { "r.17", 17, PPC_OPERAND_GPR },
+ { "r.18", 18, PPC_OPERAND_GPR },
+ { "r.19", 19, PPC_OPERAND_GPR },
+ { "r.2", 2, PPC_OPERAND_GPR },
+ { "r.20", 20, PPC_OPERAND_GPR },
+ { "r.21", 21, PPC_OPERAND_GPR },
+ { "r.22", 22, PPC_OPERAND_GPR },
+ { "r.23", 23, PPC_OPERAND_GPR },
+ { "r.24", 24, PPC_OPERAND_GPR },
+ { "r.25", 25, PPC_OPERAND_GPR },
+ { "r.26", 26, PPC_OPERAND_GPR },
+ { "r.27", 27, PPC_OPERAND_GPR },
+ { "r.28", 28, PPC_OPERAND_GPR },
+ { "r.29", 29, PPC_OPERAND_GPR },
+ { "r.3", 3, PPC_OPERAND_GPR },
+ { "r.30", 30, PPC_OPERAND_GPR },
+ { "r.31", 31, PPC_OPERAND_GPR },
+ { "r.4", 4, PPC_OPERAND_GPR },
+ { "r.5", 5, PPC_OPERAND_GPR },
+ { "r.6", 6, PPC_OPERAND_GPR },
+ { "r.7", 7, PPC_OPERAND_GPR },
+ { "r.8", 8, PPC_OPERAND_GPR },
+ { "r.9", 9, PPC_OPERAND_GPR },
+
+ { "r.sp", 1, PPC_OPERAND_GPR },
+
+ { "r.toc", 2, PPC_OPERAND_GPR },
+
+ { "r0", 0, PPC_OPERAND_GPR },
+ { "r1", 1, PPC_OPERAND_GPR },
+ { "r10", 10, PPC_OPERAND_GPR },
+ { "r11", 11, PPC_OPERAND_GPR },
+ { "r12", 12, PPC_OPERAND_GPR },
+ { "r13", 13, PPC_OPERAND_GPR },
+ { "r14", 14, PPC_OPERAND_GPR },
+ { "r15", 15, PPC_OPERAND_GPR },
+ { "r16", 16, PPC_OPERAND_GPR },
+ { "r17", 17, PPC_OPERAND_GPR },
+ { "r18", 18, PPC_OPERAND_GPR },
+ { "r19", 19, PPC_OPERAND_GPR },
+ { "r2", 2, PPC_OPERAND_GPR },
+ { "r20", 20, PPC_OPERAND_GPR },
+ { "r21", 21, PPC_OPERAND_GPR },
+ { "r22", 22, PPC_OPERAND_GPR },
+ { "r23", 23, PPC_OPERAND_GPR },
+ { "r24", 24, PPC_OPERAND_GPR },
+ { "r25", 25, PPC_OPERAND_GPR },
+ { "r26", 26, PPC_OPERAND_GPR },
+ { "r27", 27, PPC_OPERAND_GPR },
+ { "r28", 28, PPC_OPERAND_GPR },
+ { "r29", 29, PPC_OPERAND_GPR },
+ { "r3", 3, PPC_OPERAND_GPR },
+ { "r30", 30, PPC_OPERAND_GPR },
+ { "r31", 31, PPC_OPERAND_GPR },
+ { "r4", 4, PPC_OPERAND_GPR },
+ { "r5", 5, PPC_OPERAND_GPR },
+ { "r6", 6, PPC_OPERAND_GPR },
+ { "r7", 7, PPC_OPERAND_GPR },
+ { "r8", 8, PPC_OPERAND_GPR },
+ { "r9", 9, PPC_OPERAND_GPR },
+
+ { "rtoc", 2, PPC_OPERAND_GPR },
+
+ { "sdr1", 25, PPC_OPERAND_SPR },
+
+ { "sp", 1, PPC_OPERAND_GPR },
+
+ { "srr0", 26, PPC_OPERAND_SPR },
+ { "srr1", 27, PPC_OPERAND_SPR },
+
+ /* Vector (Altivec/VMX) registers */
+ { "v.0", 0, PPC_OPERAND_VR },
+ { "v.1", 1, PPC_OPERAND_VR },
+ { "v.10", 10, PPC_OPERAND_VR },
+ { "v.11", 11, PPC_OPERAND_VR },
+ { "v.12", 12, PPC_OPERAND_VR },
+ { "v.13", 13, PPC_OPERAND_VR },
+ { "v.14", 14, PPC_OPERAND_VR },
+ { "v.15", 15, PPC_OPERAND_VR },
+ { "v.16", 16, PPC_OPERAND_VR },
+ { "v.17", 17, PPC_OPERAND_VR },
+ { "v.18", 18, PPC_OPERAND_VR },
+ { "v.19", 19, PPC_OPERAND_VR },
+ { "v.2", 2, PPC_OPERAND_VR },
+ { "v.20", 20, PPC_OPERAND_VR },
+ { "v.21", 21, PPC_OPERAND_VR },
+ { "v.22", 22, PPC_OPERAND_VR },
+ { "v.23", 23, PPC_OPERAND_VR },
+ { "v.24", 24, PPC_OPERAND_VR },
+ { "v.25", 25, PPC_OPERAND_VR },
+ { "v.26", 26, PPC_OPERAND_VR },
+ { "v.27", 27, PPC_OPERAND_VR },
+ { "v.28", 28, PPC_OPERAND_VR },
+ { "v.29", 29, PPC_OPERAND_VR },
+ { "v.3", 3, PPC_OPERAND_VR },
+ { "v.30", 30, PPC_OPERAND_VR },
+ { "v.31", 31, PPC_OPERAND_VR },
+ { "v.4", 4, PPC_OPERAND_VR },
+ { "v.5", 5, PPC_OPERAND_VR },
+ { "v.6", 6, PPC_OPERAND_VR },
+ { "v.7", 7, PPC_OPERAND_VR },
+ { "v.8", 8, PPC_OPERAND_VR },
+ { "v.9", 9, PPC_OPERAND_VR },
+
+ { "v0", 0, PPC_OPERAND_VR },
+ { "v1", 1, PPC_OPERAND_VR },
+ { "v10", 10, PPC_OPERAND_VR },
+ { "v11", 11, PPC_OPERAND_VR },
+ { "v12", 12, PPC_OPERAND_VR },
+ { "v13", 13, PPC_OPERAND_VR },
+ { "v14", 14, PPC_OPERAND_VR },
+ { "v15", 15, PPC_OPERAND_VR },
+ { "v16", 16, PPC_OPERAND_VR },
+ { "v17", 17, PPC_OPERAND_VR },
+ { "v18", 18, PPC_OPERAND_VR },
+ { "v19", 19, PPC_OPERAND_VR },
+ { "v2", 2, PPC_OPERAND_VR },
+ { "v20", 20, PPC_OPERAND_VR },
+ { "v21", 21, PPC_OPERAND_VR },
+ { "v22", 22, PPC_OPERAND_VR },
+ { "v23", 23, PPC_OPERAND_VR },
+ { "v24", 24, PPC_OPERAND_VR },
+ { "v25", 25, PPC_OPERAND_VR },
+ { "v26", 26, PPC_OPERAND_VR },
+ { "v27", 27, PPC_OPERAND_VR },
+ { "v28", 28, PPC_OPERAND_VR },
+ { "v29", 29, PPC_OPERAND_VR },
+ { "v3", 3, PPC_OPERAND_VR },
+ { "v30", 30, PPC_OPERAND_VR },
+ { "v31", 31, PPC_OPERAND_VR },
+ { "v4", 4, PPC_OPERAND_VR },
+ { "v5", 5, PPC_OPERAND_VR },
+ { "v6", 6, PPC_OPERAND_VR },
+ { "v7", 7, PPC_OPERAND_VR },
+ { "v8", 8, PPC_OPERAND_VR },
+ { "v9", 9, PPC_OPERAND_VR },
+
+ /* Vector Scalar (VSX) registers (ISA 2.06). */
+ { "vs.0", 0, PPC_OPERAND_VSR },
+ { "vs.1", 1, PPC_OPERAND_VSR },
+ { "vs.10", 10, PPC_OPERAND_VSR },
+ { "vs.11", 11, PPC_OPERAND_VSR },
+ { "vs.12", 12, PPC_OPERAND_VSR },
+ { "vs.13", 13, PPC_OPERAND_VSR },
+ { "vs.14", 14, PPC_OPERAND_VSR },
+ { "vs.15", 15, PPC_OPERAND_VSR },
+ { "vs.16", 16, PPC_OPERAND_VSR },
+ { "vs.17", 17, PPC_OPERAND_VSR },
+ { "vs.18", 18, PPC_OPERAND_VSR },
+ { "vs.19", 19, PPC_OPERAND_VSR },
+ { "vs.2", 2, PPC_OPERAND_VSR },
+ { "vs.20", 20, PPC_OPERAND_VSR },
+ { "vs.21", 21, PPC_OPERAND_VSR },
+ { "vs.22", 22, PPC_OPERAND_VSR },
+ { "vs.23", 23, PPC_OPERAND_VSR },
+ { "vs.24", 24, PPC_OPERAND_VSR },
+ { "vs.25", 25, PPC_OPERAND_VSR },
+ { "vs.26", 26, PPC_OPERAND_VSR },
+ { "vs.27", 27, PPC_OPERAND_VSR },
+ { "vs.28", 28, PPC_OPERAND_VSR },
+ { "vs.29", 29, PPC_OPERAND_VSR },
+ { "vs.3", 3, PPC_OPERAND_VSR },
+ { "vs.30", 30, PPC_OPERAND_VSR },
+ { "vs.31", 31, PPC_OPERAND_VSR },
+ { "vs.32", 32, PPC_OPERAND_VSR },
+ { "vs.33", 33, PPC_OPERAND_VSR },
+ { "vs.34", 34, PPC_OPERAND_VSR },
+ { "vs.35", 35, PPC_OPERAND_VSR },
+ { "vs.36", 36, PPC_OPERAND_VSR },
+ { "vs.37", 37, PPC_OPERAND_VSR },
+ { "vs.38", 38, PPC_OPERAND_VSR },
+ { "vs.39", 39, PPC_OPERAND_VSR },
+ { "vs.4", 4, PPC_OPERAND_VSR },
+ { "vs.40", 40, PPC_OPERAND_VSR },
+ { "vs.41", 41, PPC_OPERAND_VSR },
+ { "vs.42", 42, PPC_OPERAND_VSR },
+ { "vs.43", 43, PPC_OPERAND_VSR },
+ { "vs.44", 44, PPC_OPERAND_VSR },
+ { "vs.45", 45, PPC_OPERAND_VSR },
+ { "vs.46", 46, PPC_OPERAND_VSR },
+ { "vs.47", 47, PPC_OPERAND_VSR },
+ { "vs.48", 48, PPC_OPERAND_VSR },
+ { "vs.49", 49, PPC_OPERAND_VSR },
+ { "vs.5", 5, PPC_OPERAND_VSR },
+ { "vs.50", 50, PPC_OPERAND_VSR },
+ { "vs.51", 51, PPC_OPERAND_VSR },
+ { "vs.52", 52, PPC_OPERAND_VSR },
+ { "vs.53", 53, PPC_OPERAND_VSR },
+ { "vs.54", 54, PPC_OPERAND_VSR },
+ { "vs.55", 55, PPC_OPERAND_VSR },
+ { "vs.56", 56, PPC_OPERAND_VSR },
+ { "vs.57", 57, PPC_OPERAND_VSR },
+ { "vs.58", 58, PPC_OPERAND_VSR },
+ { "vs.59", 59, PPC_OPERAND_VSR },
+ { "vs.6", 6, PPC_OPERAND_VSR },
+ { "vs.60", 60, PPC_OPERAND_VSR },
+ { "vs.61", 61, PPC_OPERAND_VSR },
+ { "vs.62", 62, PPC_OPERAND_VSR },
+ { "vs.63", 63, PPC_OPERAND_VSR },
+ { "vs.7", 7, PPC_OPERAND_VSR },
+ { "vs.8", 8, PPC_OPERAND_VSR },
+ { "vs.9", 9, PPC_OPERAND_VSR },
+
+ { "vs0", 0, PPC_OPERAND_VSR },
+ { "vs1", 1, PPC_OPERAND_VSR },
+ { "vs10", 10, PPC_OPERAND_VSR },
+ { "vs11", 11, PPC_OPERAND_VSR },
+ { "vs12", 12, PPC_OPERAND_VSR },
+ { "vs13", 13, PPC_OPERAND_VSR },
+ { "vs14", 14, PPC_OPERAND_VSR },
+ { "vs15", 15, PPC_OPERAND_VSR },
+ { "vs16", 16, PPC_OPERAND_VSR },
+ { "vs17", 17, PPC_OPERAND_VSR },
+ { "vs18", 18, PPC_OPERAND_VSR },
+ { "vs19", 19, PPC_OPERAND_VSR },
+ { "vs2", 2, PPC_OPERAND_VSR },
+ { "vs20", 20, PPC_OPERAND_VSR },
+ { "vs21", 21, PPC_OPERAND_VSR },
+ { "vs22", 22, PPC_OPERAND_VSR },
+ { "vs23", 23, PPC_OPERAND_VSR },
+ { "vs24", 24, PPC_OPERAND_VSR },
+ { "vs25", 25, PPC_OPERAND_VSR },
+ { "vs26", 26, PPC_OPERAND_VSR },
+ { "vs27", 27, PPC_OPERAND_VSR },
+ { "vs28", 28, PPC_OPERAND_VSR },
+ { "vs29", 29, PPC_OPERAND_VSR },
+ { "vs3", 3, PPC_OPERAND_VSR },
+ { "vs30", 30, PPC_OPERAND_VSR },
+ { "vs31", 31, PPC_OPERAND_VSR },
+ { "vs32", 32, PPC_OPERAND_VSR },
+ { "vs33", 33, PPC_OPERAND_VSR },
+ { "vs34", 34, PPC_OPERAND_VSR },
+ { "vs35", 35, PPC_OPERAND_VSR },
+ { "vs36", 36, PPC_OPERAND_VSR },
+ { "vs37", 37, PPC_OPERAND_VSR },
+ { "vs38", 38, PPC_OPERAND_VSR },
+ { "vs39", 39, PPC_OPERAND_VSR },
+ { "vs4", 4, PPC_OPERAND_VSR },
+ { "vs40", 40, PPC_OPERAND_VSR },
+ { "vs41", 41, PPC_OPERAND_VSR },
+ { "vs42", 42, PPC_OPERAND_VSR },
+ { "vs43", 43, PPC_OPERAND_VSR },
+ { "vs44", 44, PPC_OPERAND_VSR },
+ { "vs45", 45, PPC_OPERAND_VSR },
+ { "vs46", 46, PPC_OPERAND_VSR },
+ { "vs47", 47, PPC_OPERAND_VSR },
+ { "vs48", 48, PPC_OPERAND_VSR },
+ { "vs49", 49, PPC_OPERAND_VSR },
+ { "vs5", 5, PPC_OPERAND_VSR },
+ { "vs50", 50, PPC_OPERAND_VSR },
+ { "vs51", 51, PPC_OPERAND_VSR },
+ { "vs52", 52, PPC_OPERAND_VSR },
+ { "vs53", 53, PPC_OPERAND_VSR },
+ { "vs54", 54, PPC_OPERAND_VSR },
+ { "vs55", 55, PPC_OPERAND_VSR },
+ { "vs56", 56, PPC_OPERAND_VSR },
+ { "vs57", 57, PPC_OPERAND_VSR },
+ { "vs58", 58, PPC_OPERAND_VSR },
+ { "vs59", 59, PPC_OPERAND_VSR },
+ { "vs6", 6, PPC_OPERAND_VSR },
+ { "vs60", 60, PPC_OPERAND_VSR },
+ { "vs61", 61, PPC_OPERAND_VSR },
+ { "vs62", 62, PPC_OPERAND_VSR },
+ { "vs63", 63, PPC_OPERAND_VSR },
+ { "vs7", 7, PPC_OPERAND_VSR },
+ { "vs8", 8, PPC_OPERAND_VSR },
+ { "vs9", 9, PPC_OPERAND_VSR },
+
+ { "xer", 1, PPC_OPERAND_SPR }
};
#define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_reg))
/* Given NAME, find the register number associated with that name, return
the integer value associated with the given name or -1 on failure. */
-static int
+static const struct pd_reg *
reg_name_search (const struct pd_reg *regs, int regcount, const char *name)
{
int middle, low, high;
else if (cmp > 0)
low = middle + 1;
else
- return regs[middle].value;
+ return ®s[middle];
}
while (low <= high);
- return -1;
+ return NULL;
}
/*
static bfd_boolean
register_name (expressionS *expressionP)
{
- int reg_number;
+ const struct pd_reg *reg;
char *name;
char *start;
char c;
return FALSE;
c = get_symbol_name (&name);
- reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
+ reg = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
/* Put back the delimiting char. */
*input_line_pointer = c;
/* Look to see if it's in the register table. */
- if (reg_number >= 0)
+ if (reg != NULL)
{
expressionP->X_op = O_register;
- expressionP->X_add_number = reg_number;
+ expressionP->X_add_number = reg->value;
+ expressionP->X_md = reg->flags;
/* Make the rest nice. */
expressionP->X_add_symbol = NULL;
/* Names to recognize in a condition code. This table is sorted. */
static const struct pd_reg cr_names[] =
{
- { "cr0", 0 },
- { "cr1", 1 },
- { "cr2", 2 },
- { "cr3", 3 },
- { "cr4", 4 },
- { "cr5", 5 },
- { "cr6", 6 },
- { "cr7", 7 },
- { "eq", 2 },
- { "gt", 1 },
- { "lt", 0 },
- { "so", 3 },
- { "un", 3 }
+ { "cr0", 0, PPC_OPERAND_CR_REG },
+ { "cr1", 1, PPC_OPERAND_CR_REG },
+ { "cr2", 2, PPC_OPERAND_CR_REG },
+ { "cr3", 3, PPC_OPERAND_CR_REG },
+ { "cr4", 4, PPC_OPERAND_CR_REG },
+ { "cr5", 5, PPC_OPERAND_CR_REG },
+ { "cr6", 6, PPC_OPERAND_CR_REG },
+ { "cr7", 7, PPC_OPERAND_CR_REG },
+ { "eq", 2, PPC_OPERAND_CR_BIT },
+ { "gt", 1, PPC_OPERAND_CR_BIT },
+ { "lt", 0, PPC_OPERAND_CR_BIT },
+ { "so", 3, PPC_OPERAND_CR_BIT },
+ { "un", 3, PPC_OPERAND_CR_BIT }
};
/* Parsing function. This returns non-zero if it recognized an
int
ppc_parse_name (const char *name, expressionS *exp)
{
- int val;
+ const struct pd_reg *reg;
if (! cr_operand)
return 0;
if (*name == '%')
++name;
- val = reg_name_search (cr_names, sizeof cr_names / sizeof cr_names[0],
+ reg = reg_name_search (cr_names, sizeof cr_names / sizeof cr_names[0],
name);
- if (val < 0)
+ if (reg == NULL)
return 0;
- exp->X_op = O_constant;
- exp->X_add_number = val;
+ exp->X_op = O_register;
+ exp->X_add_number = reg->value;
+ exp->X_md = reg->flags;
return 1;
}
+
+/* Propagate X_md and check register expressions. This is to support
+ condition codes like 4*cr5+eq. */
+
+int
+ppc_optimize_expr (expressionS *left, operatorT op, expressionS *right)
+{
+ /* Accept 4*cr<n> and cr<n>*4. */
+ if (op == O_multiply
+ && ((right->X_op == O_register
+ && right->X_md == PPC_OPERAND_CR_REG
+ && left->X_op == O_constant
+ && left->X_add_number == 4)
+ || (left->X_op == O_register
+ && left->X_md == PPC_OPERAND_CR_REG
+ && right->X_op == O_constant
+ && right->X_add_number == 4)))
+ {
+ left->X_op = O_register;
+ left->X_md = PPC_OPERAND_CR_REG | PPC_OPERAND_CR_BIT;
+ left->X_add_number *= right->X_add_number;
+ return 1;
+ }
+
+ /* Accept the above plus <cr bit>, and <cr bit> plus the above. */
+ if (right->X_op == O_register
+ && left->X_op == O_register
+ && op == O_add
+ && ((right->X_md == PPC_OPERAND_CR_BIT
+ && left->X_md == (PPC_OPERAND_CR_REG | PPC_OPERAND_CR_BIT))
+ || (right->X_md == (PPC_OPERAND_CR_REG | PPC_OPERAND_CR_BIT)
+ && left->X_md == PPC_OPERAND_CR_BIT)))
+ {
+ left->X_md = PPC_OPERAND_CR_BIT;
+ right->X_op = O_constant;
+ return 0;
+ }
+
+ /* Accept reg +/- constant. */
+ if (left->X_op == O_register
+ && !((op == O_add || op == O_subtract) && right->X_op == O_constant))
+ as_warn (_("invalid register expression"));
+
+ /* Accept constant + reg. */
+ if (right->X_op == O_register)
+ {
+ if (op == O_add && left->X_op == O_constant)
+ left->X_md = right->X_md;
+ else
+ as_warn (_("invalid register expression"));
+ }
+
+ return 0;
+}
\f
/* Local variables. */
case 'm':
new_cpu = ppc_parse_cpu (ppc_cpu, &sticky, arg);
- if (new_cpu != 0)
+ /* "raw" is only valid for the disassembler. */
+ if (new_cpu != 0 && (new_cpu & PPC_OPCODE_RAW) == 0)
{
ppc_cpu = new_cpu;
if (strcmp (arg, "vle") == 0)
}
}
+ else if (strcmp (arg, "no-vle") == 0)
+ {
+ sticky &= ~PPC_OPCODE_VLE;
+
+ new_cpu = ppc_parse_cpu (ppc_cpu, &sticky, "booke");
+ new_cpu &= ~PPC_OPCODE_VLE;
+
+ ppc_cpu = new_cpu;
+ }
+
else if (strcmp (arg, "regnames") == 0)
reg_names_p = TRUE;
msolaris = FALSE;
ppc_comment_chars = ppc_eabi_comment_chars;
}
+ else if (strcmp (arg, "spe2") == 0)
+ {
+ ppc_cpu |= PPC_OPCODE_SPE2;
+ }
#endif
else
{
-mpower8, -mpwr8 generate code for Power8 architecture\n\
-mpower9, -mpwr9 generate code for Power9 architecture\n\
-mcell generate code for Cell Broadband Engine architecture\n\
--mcom generate code Power/PowerPC common instructions\n\
+-mcom generate code for 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\
--mhtm generate code for Hardware Transactional Memory\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\
-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\
+-mspe2 generate code for Freescale SPE2 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\
insn_validate (const struct powerpc_opcode *op)
{
const unsigned char *o;
- unsigned long omask = op->mask;
+ uint64_t omask = op->mask;
/* The mask had better not trim off opcode bits. */
if ((op->opcode & omask) != op->opcode)
const struct powerpc_operand *operand = &powerpc_operands[*o];
if (operand->shift != (int) PPC_OPSHIFT_INV)
{
- unsigned long mask;
+ uint64_t mask;
if (operand->shift >= 0)
mask = operand->bitm << operand->shift;
all the 1's in the mask are contiguous. */
for (i = 0; i < num_powerpc_operands; ++i)
{
- unsigned long mask = powerpc_operands[i].bitm;
- unsigned long right_bit;
+ uint64_t mask = powerpc_operands[i].bitm;
+ uint64_t right_bit;
unsigned int j;
right_bit = mask & -mask;
int new_opcode = PPC_OP (op[0].opcode);
#ifdef PRINT_OPCODE_TABLE
- printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+ printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%llx\tmask: 0x%llx\tflags: 0x%llx\n",
op->name, (unsigned int) (op - powerpc_opcodes),
- (unsigned int) new_opcode, (unsigned int) op->opcode,
- (unsigned int) op->mask, (unsigned long long) op->flags);
+ (unsigned int) new_opcode, (unsigned long long) op->opcode,
+ (unsigned long long) op->mask, (unsigned long long) op->flags);
#endif
/* The major opcodes had better be sorted. Code in the
new_seg = VLE_OP_TO_SEG (new_seg);
#ifdef PRINT_OPCODE_TABLE
- printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+ printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%llx\tmask: 0x%llx\tflags: 0x%llx\n",
op->name, (unsigned int) (op - powerpc_opcodes),
- (unsigned int) new_seg, (unsigned int) op->opcode,
- (unsigned int) op->mask, (unsigned long long) op->flags);
+ (unsigned int) new_seg, (unsigned long long) op->opcode,
+ (unsigned long long) 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
}
}
+ /* SPE2 instructions */
+ if ((ppc_cpu & PPC_OPCODE_SPE2) == PPC_OPCODE_SPE2)
+ {
+ op_end = spe2_opcodes + spe2_num_opcodes;
+ for (op = spe2_opcodes; op < op_end; op++)
+ {
+ if (ENABLE_CHECKING)
+ {
+ if (op != spe2_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);
+
+ /* 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 && !(ppc_cpu & op->deprecated))
+ {
+ const char *retval;
+
+ retval = hash_insert (ppc_hash, op->name, (void *) op);
+ if (retval != NULL)
+ {
+ as_bad (_("duplicate instruction %s"),
+ op->name);
+ bad_insn = TRUE;
+ }
+ }
+ }
+
+ for (op = spe2_opcodes; op < op_end; op++)
+ hash_insert (ppc_hash, op->name, (void *) op);
+ }
+
/* Insert the macros into a hash table. */
ppc_macro_hash = hash_new ();
/* Insert an operand value into an instruction. */
-static unsigned long
-ppc_insert_operand (unsigned long insn,
+static uint64_t
+ppc_insert_operand (uint64_t insn,
const struct powerpc_operand *operand,
- offsetT val,
+ int64_t val,
ppc_cpu_t cpu,
const char *file,
unsigned int line)
{
- long min, max, right;
+ int64_t min, max, right;
max = operand->bitm;
right = max & -max;
if ((operand->flags & PPC_OPERAND_NEGATIVE) != 0)
{
- long tmp = min;
+ int64_t tmp = min;
min = -max;
max = -tmp;
}
sign extend the 32-bit value to 64 bits if so doing makes the
value valid. */
if (val > max
- && (offsetT) (val - 0x80000000 - 0x80000000) >= min
- && (offsetT) (val - 0x80000000 - 0x80000000) <= max
- && ((val - 0x80000000 - 0x80000000) & (right - 1)) == 0)
- val = val - 0x80000000 - 0x80000000;
+ && (val - (1LL << 32)) >= min
+ && (val - (1LL << 32)) <= max
+ && ((val - (1LL << 32)) & (right - 1)) == 0)
+ val = val - (1LL << 32);
/* Similarly, people write expressions like ~(1<<15), and expect
this to be OK for a 32-bit unsigned value. */
else if (val < min
- && (offsetT) (val + 0x80000000 + 0x80000000) >= min
- && (offsetT) (val + 0x80000000 + 0x80000000) <= max
- && ((val + 0x80000000 + 0x80000000) & (right - 1)) == 0)
- val = val + 0x80000000 + 0x80000000;
+ && (val + (1LL << 32)) >= min
+ && (val + (1LL << 32)) <= max
+ && ((val + (1LL << 32)) & (right - 1)) == 0)
+ val = val + (1LL << 32);
else if (val < min
|| val > max
const char *errmsg;
errmsg = NULL;
- insn = (*operand->insert) (insn, (long) val, cpu, &errmsg);
+ insn = (*operand->insert) (insn, val, cpu, &errmsg);
if (errmsg != (const char *) NULL)
as_bad_where (file, line, "%s", errmsg);
}
else if (operand->shift >= 0)
- insn |= ((long) val & operand->bitm) << operand->shift;
+ insn |= (val & operand->bitm) << operand->shift;
else
- insn |= ((long) val & operand->bitm) >> -operand->shift;
+ insn |= (val & operand->bitm) >> -operand->shift;
return insn;
}
{
char *s;
const struct powerpc_opcode *opcode;
- unsigned long insn;
+ uint64_t insn;
const unsigned char *opindex_ptr;
int skip_optional;
int need_paren;
&& !((operand->flags & PPC_OPERAND_OPTIONAL32) != 0 && ppc_obj64)
&& skip_optional)
{
- long val = ppc_optional_operand_value (operand);
+ int64_t val = ppc_optional_operand_value (operand);
if (operand->insert)
{
insn = (*operand->insert) (insn, val, ppc_cpu, &errmsg);
as_bad ("%s", errmsg);
}
else if (operand->shift >= 0)
- insn |= ((long) val & operand->bitm) << operand->shift;
+ insn |= (val & operand->bitm) << operand->shift;
else
- insn |= ((long) val & operand->bitm) >> -operand->shift;
+ insn |= (val & operand->bitm) >> -operand->shift;
if ((operand->flags & PPC_OPERAND_NEXT) != 0)
next_opindex = *opindex_ptr + 1;
as_bad (_("missing operand"));
else if (ex.X_op == O_register)
{
+ if ((ex.X_md
+ & ~operand->flags
+ & (PPC_OPERAND_GPR | PPC_OPERAND_FPR | PPC_OPERAND_VR
+ | PPC_OPERAND_VSR | PPC_OPERAND_CR_BIT | PPC_OPERAND_CR_REG
+ | PPC_OPERAND_SPR | PPC_OPERAND_GQR)) != 0
+ && !((ex.X_md & PPC_OPERAND_GPR) != 0
+ && ex.X_add_number != 0
+ && (operand->flags & PPC_OPERAND_GPR_0) != 0))
+ as_warn (_("invalid register expression"));
insn = ppc_insert_operand (insn, operand, ex.X_add_number,
ppc_cpu, (char *) NULL, 0);
}
/* addpcis. */
if (opcode->opcode == (19 << 26) + (2 << 1)
&& reloc == BFD_RELOC_HI16_S)
- reloc = BFD_RELOC_PPC_REL16DX_HA;
+ reloc = BFD_RELOC_PPC_16DX_HA;
/* If VLE-mode convert LO/HI/HA relocations. */
if (opcode->flags & PPC_OPCODE_VLE)
{
- int tmp_insn = insn & opcode->mask;
+ uint64_t tmp_insn = insn & opcode->mask;
int use_a_reloc = (tmp_insn == E_OR2I_INSN
|| tmp_insn == E_AND2I_DOT_INSN
return flags;
}
+
+bfd_vma
+ppc_elf_section_letter (int letter, const char **ptrmsg)
+{
+ if (letter == 'v')
+ return SHF_PPC_VLE;
+
+ *ptrmsg = _("bad .section directive: want a,e,v,w,x,M,S,G,T in string");
+ return -1;
+}
#endif /* OBJ_ELF */
\f
(In principle, there's no reason why the relocations _have_ to be at
the beginning. Anywhere in the csect would do. However, inserting
- at the beginning is what the native assmebler does, and it helps to
+ at the beginning is what the native assembler does, and it helps to
deal with cases where the .ref statements follow the section contents.)
??? .refs don't work for empty .csects. However, the native assembler
initial: .section .reldata "drw3"
d - initialized data
r - readable
- w - writeable
+ w - writable
3 - double word aligned (that would be 8 byte boundary)
commentary:
*
* Section Protection:
* 'r' - section is readable
- * 'w' - section is writeable
+ * 'w' - section is writable
* 'x' - section is executable
* 's' - section is sharable
*
* Section Alignment:
* '0' - align to byte boundary
- * '1' - align to halfword undary
+ * '1' - align to halfword boundary
* '2' - align to word boundary
* '3' - align to doubleword boundary
* '4' - align to quadword boundary
case 'r': /* section is readable */
flags |= IMAGE_SCN_MEM_READ;
break;
- case 'w': /* section is writeable */
+ case 'w': /* section is writable */
flags |= IMAGE_SCN_MEM_WRITE;
break;
case 'x': /* section is executable */
}
#endif
- if (fixP->fx_subsy != (symbolS *) NULL)
+ /* We are only able to convert some relocs to pc-relative. */
+ if (fixP->fx_pcrel)
+ {
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_LO16:
+ fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
+ break;
+
+ case BFD_RELOC_HI16:
+ fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
+ break;
+
+ case BFD_RELOC_HI16_S:
+ fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
+ break;
+
+ case BFD_RELOC_64:
+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
+ break;
+
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ break;
+
+ case BFD_RELOC_16:
+ fixP->fx_r_type = BFD_RELOC_16_PCREL;
+ break;
+
+ case BFD_RELOC_PPC_16DX_HA:
+ fixP->fx_r_type = BFD_RELOC_PPC_REL16DX_HA;
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (!fixP->fx_done
+ && fixP->fx_r_type == BFD_RELOC_PPC_16DX_HA)
{
- /* We can't actually support subtracting a symbol. */
- as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
+ /* addpcis is relative to next insn address. */
+ value -= 4;
+ fixP->fx_r_type = BFD_RELOC_PPC_REL16DX_HA;
+ fixP->fx_pcrel = 1;
}
operand = NULL;
case BFD_RELOC_HI16_S:
case BFD_RELOC_HI16_S_PCREL:
+ case BFD_RELOC_PPC_16DX_HA:
case BFD_RELOC_PPC_REL16DX_HA:
#ifdef OBJ_ELF
if (REPORT_OVERFLOW_HI && ppc_obj64)
_("data in executable section"));
}
- /* We are only able to convert some relocs to pc-relative. */
- if (!fixP->fx_done && fixP->fx_pcrel)
- {
- switch (fixP->fx_r_type)
- {
- case BFD_RELOC_LO16:
- fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
- break;
-
- case BFD_RELOC_HI16:
- fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
- break;
-
- case BFD_RELOC_HI16_S:
- fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
- break;
-
- case BFD_RELOC_64:
- fixP->fx_r_type = BFD_RELOC_64_PCREL;
- break;
-
- case BFD_RELOC_32:
- fixP->fx_r_type = BFD_RELOC_32_PCREL;
- break;
-
- case BFD_RELOC_16:
- fixP->fx_r_type = BFD_RELOC_16_PCREL;
- break;
-
- /* Some of course are already pc-relative. */
- case BFD_RELOC_LO16_PCREL:
- case BFD_RELOC_HI16_PCREL:
- case BFD_RELOC_HI16_S_PCREL:
- case BFD_RELOC_PPC_REL16DX_HA:
- case BFD_RELOC_64_PCREL:
- case BFD_RELOC_32_PCREL:
- case BFD_RELOC_16_PCREL:
- case BFD_RELOC_PPC_B16:
- case BFD_RELOC_PPC_B16_BRTAKEN:
- case BFD_RELOC_PPC_B16_BRNTAKEN:
- case BFD_RELOC_PPC_B26:
- case BFD_RELOC_PPC_LOCAL24PC:
- case BFD_RELOC_24_PLT_PCREL:
- case BFD_RELOC_32_PLT_PCREL:
- case BFD_RELOC_64_PLT_PCREL:
- case BFD_RELOC_PPC_VLE_REL8:
- case BFD_RELOC_PPC_VLE_REL15:
- case BFD_RELOC_PPC_VLE_REL24:
- break;
-
- default:
- if (fixP->fx_addsy)
- {
- const char *sfile;
- unsigned int sline;
-
- /* Use expr_symbol_where to see if this is an
- expression symbol. */
- if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("unresolved expression that must"
- " be resolved"));
- else
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("cannot emit PC relative %s relocation"
- " against %s"),
- bfd_get_reloc_code_name (fixP->fx_r_type),
- S_GET_NAME (fixP->fx_addsy));
- }
- else
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("unable to resolve expression"));
- fixP->fx_done = 1;
- break;
- }
- }
-
#ifdef OBJ_ELF
ppc_elf_validate_fix (fixP, seg);
fixP->fx_addnumber = value;