📄 cpu-ia64-opc.c
字号:
/* Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc. Contributed by David Mosberger-Tang <davidm@hpl.hp.com>This file is part of BFD, the Binary File Descriptor library.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, 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 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. --davidm Mon Apr 13 22:14:02 1998 */#include "ia64-opc.h"#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))static const char*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 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 ATTRIBUTE_UNUSED, ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED){ return 0;}static const char*ext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED, ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED){ return 0;}static const char*ins_reg (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ if (value >= 1u << self->field[0].bits) return "register number out of range"; *code |= value << self->field[0].shift; return 0;}static const char*ext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep){ *valuep = ((code >> self->field[0].shift) & ((1u << self->field[0].bits) - 1)); return 0;}static const char*ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ ia64_insn new = 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); value >>= self->field[i].bits; } if (value) return "integer operand out of range"; *code |= new; return 0;}static const char*ext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep){ BFD_HOST_U_64_BIT value = 0; int i, bits = 0, total = 0; for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) { bits = self->field[i].bits; value |= ((code >> self->field[i].shift) & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total; total += bits; } *valuep = value; 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){ if (value & 0x7) return "value not an integer multiple of 8"; return ins_immu (self, value >> 3, code);}static const char*ext_immus8 (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 << 3; return 0;}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 = 0; ia64_insn new = 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); 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; return 0;}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; BFD_HOST_64_BIT val = 0, sign; for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) { bits = self->field[i].bits; val |= ((code >> self->field[i].shift) & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total; total += bits; } /* sign extend: */ sign = (BFD_HOST_64_BIT) 1 << (total - 1); val = (val ^ sign) - sign; *valuep = (val << scale); return 0;}static const char*ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ return ins_imms_scaled (self, value, code, 0);}static const char*ins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; return ins_imms_scaled (self, value, code, 0);}static const char*ext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep){ return ext_imms_scaled (self, code, valuep, 0);}static const char*ins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ --value; return ins_imms_scaled (self, value, code, 0);}static const char*ins_immsm1u4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; --value; return ins_imms_scaled (self, value, code, 0);}static const char*ext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep){ const char *res = ext_imms_scaled (self, code, valuep, 0); ++*valuep; return res;}static const char*ins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ return ins_imms_scaled (self, value, code, 1);}static const char*ext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep){ return ext_imms_scaled (self, code, valuep, 1);}static const char*ins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ return ins_imms_scaled (self, value, code, 4);}static const char*ext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep){ return ext_imms_scaled (self, code, valuep, 4);}static const char*ins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ return ins_imms_scaled (self, value, code, 16);}static const char*ext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep){ return ext_imms_scaled (self, code, valuep, 16);}static const char*ins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code){ ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1; return ins_immu (self, value ^ mask, code);}static const char*ext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep){ const char *result; ia64_insn mask; mask = (((ia64_insn) 1) << self->field[0].bits) - 1; result = ext_immu (self, code, valuep); if (!result) { mask = (((ia64_insn) 1) << self->field[0].bits) - 1; *valuep ^= mask; } return result;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -