X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcpu-ia64-opc.c;h=d3e8f6ff44f64faa03327f7e99e86da46b86e1d1;hb=65281396861dfcfa993eb5af4769d6837104890d;hp=36de3c818e20adddcfe47864865526a0d3fe417c;hpb=71f6b58639da628af9accaef2b58249c5a60679a;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/cpu-ia64-opc.c b/bfd/cpu-ia64-opc.c index 36de3c818e..d3e8f6ff44 100644 --- a/bfd/cpu-ia64-opc.c +++ b/bfd/cpu-ia64-opc.c @@ -1,25 +1,26 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1998-2017 Free Software Foundation, Inc. Contributed by David Mosberger-Tang -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ /* Logically, this code should be part of libopcode but since some of the operand insertion/extraction functions help bfd to implement - relocations, this code is included as part of elf64-ia64.c. This + relocations, this code is included as part of cpu-ia64.c. This avoids circular dependencies between libopcode and libbfd and also obviates the need for applications to link in libopcode when all they really want is libbfd. @@ -31,25 +32,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0]))) static const char* -ins_rsvd (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) +ins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED, + ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED) { return "internal error---this shouldn't happen"; } static const char* -ext_rsvd (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) +ext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED, + ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED) { return "internal error---this shouldn't happen"; } static const char* -ins_const (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) +ins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED, + ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED) { return 0; } static const char* -ext_const (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) +ext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED, + ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED) { return 0; } @@ -75,19 +80,19 @@ ext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) static const char* ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) { - ia64_insn new = 0; + ia64_insn new_insn = 0; int i; for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) { - new |= ((value & ((((ia64_insn) 1) << self->field[i].bits) - 1)) - << self->field[i].shift); + new_insn |= ((value & ((((ia64_insn) 1) << self->field[i].bits) - 1)) + << self->field[i].shift); value >>= self->field[i].bits; } if (value) return "integer operand out of range"; - *code |= new; + *code |= new_insn; return 0; } @@ -108,6 +113,29 @@ ext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) return 0; } +static const char* +ins_immu5b (const struct ia64_operand *self, ia64_insn value, + ia64_insn *code) +{ + if (value < 32 || value > 63) + return "value must be between 32 and 63"; + return ins_immu (self, value - 32, code); +} + +static const char* +ext_immu5b (const struct ia64_operand *self, ia64_insn code, + ia64_insn *valuep) +{ + const char *result; + + result = ext_immu (self, code, valuep); + if (result) + return result; + + *valuep = *valuep + 32; + return 0; +} + static const char* ins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) { @@ -133,23 +161,23 @@ static const char* ins_imms_scaled (const struct ia64_operand *self, ia64_insn value, ia64_insn *code, int scale) { - BFD_HOST_64_BIT svalue = value, sign_bit; - ia64_insn new = 0; + BFD_HOST_64_BIT svalue = value, sign_bit = 0; + ia64_insn new_insn = 0; int i; svalue >>= scale; for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) { - new |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1)) - << self->field[i].shift); + new_insn |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1)) + << self->field[i].shift); sign_bit = (svalue >> (self->field[i].bits - 1)) & 1; svalue >>= self->field[i].bits; } if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1)) return "integer operand out of range"; - *code |= new; + *code |= new_insn; return 0; } @@ -157,8 +185,8 @@ static const char* ext_imms_scaled (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep, int scale) { - int i, bits = 0, total = 0, shift; - BFD_HOST_64_BIT val = 0; + int i, bits = 0, total = 0; + BFD_HOST_64_BIT val = 0, sign; for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) { @@ -168,8 +196,8 @@ ext_imms_scaled (const struct ia64_operand *self, ia64_insn code, total += bits; } /* sign extend: */ - shift = 8*sizeof (val) - total; - val = (val << shift) >> shift; + sign = (BFD_HOST_64_BIT) 1 << (total - 1); + val = (val ^ sign) - sign; *valuep = (val << scale); return 0; @@ -184,10 +212,7 @@ ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) static const char* ins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) { - if (value == (BFD_HOST_U_64_BIT) 0x100000000) - value = 0; - else - value = (((BFD_HOST_64_BIT)value << 32) >> 32); + value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; return ins_imms_scaled (self, value, code, 0); } @@ -209,10 +234,7 @@ static const char* ins_immsm1u4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) { - if (value == (BFD_HOST_U_64_BIT) 0x100000000) - value = 0; - else - value = (((BFD_HOST_64_BIT)value << 32) >> 32); + value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; --value; return ins_imms_scaled (self, value, code, 0); @@ -356,6 +378,46 @@ ext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) return 0; } +static const char* +ins_cnt6a (const struct ia64_operand *self, ia64_insn value, + ia64_insn *code) +{ + if (value < 1 || value > 64) + return "value must be between 1 and 64"; + return ins_immu (self, value - 1, code); +} + +static const char* +ext_cnt6a (const struct ia64_operand *self, ia64_insn code, + ia64_insn *valuep) +{ + const char *result; + + result = ext_immu (self, code, valuep); + if (result) + return result; + + *valuep = *valuep + 1; + return 0; +} + +static const char* +ins_strd5b (const struct ia64_operand *self, ia64_insn value, + ia64_insn *code) +{ + if ( value & 0x3f ) + return "value must be a multiple of 64"; + return ins_imms_scaled (self, value, code, 6); +} + +static const char* +ext_strd5b (const struct ia64_operand *self, ia64_insn code, + ia64_insn *valuep) +{ + return ext_imms_scaled (self, code, valuep, 6); +} + + static const char* ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) { @@ -413,19 +475,20 @@ ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] = { /* constants: */ - { CST, ins_const, ext_const, "NIL", {{ 0, }}, 0, "" }, - { CST, ins_const, ext_const, "ar.ccv", {{ 0, }}, 0, "ar.ccv" }, - { CST, ins_const, ext_const, "ar.pfs", {{ 0, }}, 0, "ar.pfs" }, - { CST, ins_const, ext_const, "1", {{ 0, }}, 0, "1" }, - { CST, ins_const, ext_const, "8", {{ 0, }}, 0, "1" }, - { CST, ins_const, ext_const, "16", {{ 0, }}, 0, "16" }, - { CST, ins_const, ext_const, "r0", {{ 0, }}, 0, "r0" }, - { CST, ins_const, ext_const, "ip", {{ 0, }}, 0, "ip" }, - { CST, ins_const, ext_const, "pr", {{ 0, }}, 0, "pr" }, - { CST, ins_const, ext_const, "pr.rot", {{ 0, }}, 0, "pr.rot" }, - { CST, ins_const, ext_const, "psr", {{ 0, }}, 0, "psr" }, - { CST, ins_const, ext_const, "psr.l", {{ 0, }}, 0, "psr.l" }, - { CST, ins_const, ext_const, "psr.um", {{ 0, }}, 0, "psr.um" }, + { CST, ins_const, ext_const, "NIL", {{ 0, 0}}, 0, "" }, + { CST, ins_const, ext_const, "ar.csd", {{ 0, 0}}, 0, "ar.csd" }, + { CST, ins_const, ext_const, "ar.ccv", {{ 0, 0}}, 0, "ar.ccv" }, + { CST, ins_const, ext_const, "ar.pfs", {{ 0, 0}}, 0, "ar.pfs" }, + { CST, ins_const, ext_const, "1", {{ 0, 0}}, 0, "1" }, + { CST, ins_const, ext_const, "8", {{ 0, 0}}, 0, "8" }, + { CST, ins_const, ext_const, "16", {{ 0, 0}}, 0, "16" }, + { CST, ins_const, ext_const, "r0", {{ 0, 0}}, 0, "r0" }, + { CST, ins_const, ext_const, "ip", {{ 0, 0}}, 0, "ip" }, + { CST, ins_const, ext_const, "pr", {{ 0, 0}}, 0, "pr" }, + { CST, ins_const, ext_const, "pr.rot", {{ 0, 0}}, 0, "pr.rot" }, + { CST, ins_const, ext_const, "psr", {{ 0, 0}}, 0, "psr" }, + { CST, ins_const, ext_const, "psr.l", {{ 0, 0}}, 0, "psr.l" }, + { CST, ins_const, ext_const, "psr.um", {{ 0, 0}}, 0, "psr.um" }, /* register operands: */ { REG, ins_reg, ext_reg, "ar", {{ 7, 20}}, 0, /* AR3 */ @@ -456,6 +519,12 @@ const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] = "a general register" }, { REG, ins_reg, ext_reg, "r", {{ 2, 20}}, 0, /* R3_2 */ "a general register r0-r3" }, + { REG, ins_reg, ext_reg, "dahr", {{ 3, 23}}, 0, /* DAHR */ + "a dahr register dahr0-7" }, + + /* memory operands: */ + { IND, ins_reg, ext_reg, "", {{7, 20}}, 0, /* MR3 */ + "a memory address" }, /* indirect operands: */ { IND, ins_reg, ext_reg, "cpuid", {{7, 20}}, 0, /* CPUID_R3 */ @@ -468,8 +537,6 @@ const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] = "an itr register" }, { IND, ins_reg, ext_reg, "ibr", {{7, 20}}, 0, /* IBR_R3 */ "an ibr register" }, - { IND, ins_reg, ext_reg, "", {{7, 20}}, 0, /* MR3 */ - "an indirect memory address" }, { IND, ins_reg, ext_reg, "msr", {{7, 20}}, 0, /* MSR_R3 */ "an msr register" }, { IND, ins_reg, ext_reg, "pkr", {{7, 20}}, 0, /* PKR_R3 */ @@ -478,6 +545,8 @@ const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] = "a pmc register" }, { IND, ins_reg, ext_reg, "pmd", {{7, 20}}, 0, /* PMD_R3 */ "a pmd register" }, + { IND, ins_reg, ext_reg, "dahr", {{7, 20}}, 0, /* DAHR_R3 */ + "a dahr register" }, { IND, ins_reg, ext_reg, "rr", {{7, 20}}, 0, /* RR_R3 */ "an rr register" }, @@ -504,6 +573,8 @@ const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] = "a 1-bit integer (-1, 0)" }, { ABS, ins_immu, ext_immu, 0, {{ 2, 13}}, UDEC, /* IMMU2 */ "a 2-bit unsigned (0-3)" }, + { ABS, ins_immu5b, ext_immu5b, 0, {{ 5, 14}}, UDEC, /* IMMU5b */ + "a 5-bit unsigned (32 + (0-31))" }, { ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, 0, /* IMMU7a */ "a 7-bit unsigned (0-127)" }, { ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, 0, /* IMMU7b */ @@ -540,14 +611,20 @@ const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] = { ABS, ins_imms, ext_imms, 0, /* IMM14 */ {{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC, "a 14-bit integer (-8192-8191)" }, + { ABS, ins_immu, ext_immu, 0, /* IMMU16 */ + {{4, 6}, {11, 12}, { 1, 36}}, UDEC, + "a 16-bit unsigned" }, { ABS, ins_imms1, ext_imms1, 0, /* IMM17 */ {{ 7, 6}, { 8, 24}, { 1, 36}}, 0, "a 17-bit integer (-65536-65535)" }, + { ABS, ins_immu, ext_immu, 0, /* IMMU19 */ + {{4, 6}, {14, 12}, { 1, 36}}, UDEC, + "a 19-bit unsigned" }, { ABS, ins_immu, ext_immu, 0, {{20, 6}, { 1, 36}}, 0, /* IMMU21 */ "a 21-bit unsigned" }, { ABS, ins_imms, ext_imms, 0, /* IMM22 */ {{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC, - "a 22-bit integer" }, + "a 22-bit signed integer" }, { ABS, ins_immu, ext_immu, 0, /* IMMU24 */ {{21, 6}, { 2, 31}, { 1, 36}}, 0, "a 24-bit unsigned" }, @@ -582,4 +659,11 @@ const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] = "a branch target" }, { REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* TGT64 */ "a branch target" }, + + { ABS, ins_const, ext_const, 0, {{0, 0}}, 0, /* LDXMOV */ + "ldxmov target" }, + { ABS, ins_cnt6a, ext_cnt6a, 0, {{6, 6}}, UDEC, /* CNT6a */ + "lfetch count" }, + { ABS, ins_strd5b, ext_strd5b, 0, {{5, 13}}, SDEC, /* STRD5b*/ + "lfetch stride" }, };