v850-opc.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 787 行 · 第 1/2 页
C
787 行
/* Assemble V850 instructions. Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "sysdep.h"#include "opcode/v850.h"#include <stdio.h>#include "opintl.h"/* regular opcode */#define OP(x) ((x & 0x3f) << 5)#define OP_MASK OP (0x3f)/* conditional branch opcode */#define BOP(x) ((0x0b << 7) | (x & 0x0f))#define BOP_MASK ((0x0f << 7) | 0x0f)/* one-word opcodes */#define one(x) ((unsigned int) (x))/* two-word opcodes */#define two(x,y) ((unsigned int) (x) | ((unsigned int) (y) << 16))/* The functions used to insert and extract complicated operands. *//* Note: There is a conspiracy between these functions and v850_insert_operand() in gas/config/tc-v850.c. Error messages containing the string 'out of range' will be ignored unless a specific command line option is given to GAS. */static const char * not_valid = N_ ("displacement value is not in range and is not aligned");static const char * out_of_range = N_ ("displacement value is out of range");static const char * not_aligned = N_ ("displacement value is not aligned");static const char * immediate_out_of_range = N_ ("immediate value is out of range");static unsigned longinsert_d9 (insn, value, errmsg) unsigned long insn; long value; const char ** errmsg;{ if (value > 0xff || value < -0x100) { if ((value % 2) != 0) * errmsg = _("branch value not in range and to odd offset"); else * errmsg = _("branch value out of range"); } else if ((value % 2) != 0) * errmsg = _("branch to odd offset"); return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3));}static unsigned longextract_d9 (insn, invalid) unsigned long insn; int * invalid;{ unsigned long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3); if ((insn & 0x8000) != 0) ret -= 0x0200; return ret;}static unsigned longinsert_d22 (insn, value, errmsg) unsigned long insn; long value; const char ** errmsg;{ if (value > 0x1fffff || value < -0x200000) { if ((value % 2) != 0) * errmsg = _("branch value not in range and to an odd offset"); else * errmsg = _("branch value out of range"); } else if ((value % 2) != 0) * errmsg = _("branch to odd offset"); return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));}static unsigned longextract_d22 (insn, invalid) unsigned long insn; int * invalid;{ signed long ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16); return (unsigned long) ((ret << 10) >> 10);}static unsigned longinsert_d16_15 (insn, value, errmsg) unsigned long insn; long value; const char ** errmsg;{ if (value > 0x7fff || value < -0x8000) { if ((value % 2) != 0) * errmsg = _(not_valid); else * errmsg = _(out_of_range); } else if ((value % 2) != 0) * errmsg = _(not_aligned); return insn | ((value & 0xfffe) << 16);}static unsigned longextract_d16_15 (insn, invalid) unsigned long insn; int * invalid;{ signed long ret = (insn & 0xfffe0000); return ret >> 16;}static unsigned longinsert_d8_7 (insn, value, errmsg) unsigned long insn; long value; const char ** errmsg;{ if (value > 0xff || value < 0) { if ((value % 2) != 0) * errmsg = _(not_valid); else * errmsg = _(out_of_range); } else if ((value % 2) != 0) * errmsg = _(not_aligned); value >>= 1; return (insn | (value & 0x7f));}static unsigned longextract_d8_7 (insn, invalid) unsigned long insn; int * invalid;{ unsigned long ret = (insn & 0x7f); return ret << 1;}static unsigned longinsert_d8_6 (insn, value, errmsg) unsigned long insn; long value; const char ** errmsg;{ if (value > 0xff || value < 0) { if ((value % 4) != 0) *errmsg = _(not_valid); else * errmsg = _(out_of_range); } else if ((value % 4) != 0) * errmsg = _(not_aligned); value >>= 1; return (insn | (value & 0x7e));}static unsigned longextract_d8_6 (insn, invalid) unsigned long insn; int * invalid;{ unsigned long ret = (insn & 0x7e); return ret << 1;}static unsigned longinsert_d5_4 (insn, value, errmsg) unsigned long insn; long value; const char ** errmsg;{ if (value > 0x1f || value < 0) { if (value & 1) * errmsg = _(not_valid); else *errmsg = _(out_of_range); } else if (value & 1) * errmsg = _(not_aligned); value >>= 1; return (insn | (value & 0x0f));}static unsigned longextract_d5_4 (insn, invalid) unsigned long insn; int * invalid;{ unsigned long ret = (insn & 0x0f); return ret << 1;}static unsigned longinsert_d16_16 (insn, value, errmsg) unsigned long insn; signed long value; const char ** errmsg;{ if (value > 0x7fff || value < -0x8000) * errmsg = _(out_of_range); return (insn | ((value & 0xfffe) << 16) | ((value & 1) << 5));}static unsigned longextract_d16_16 (insn, invalid) unsigned long insn; int * invalid;{ signed long ret = insn & 0xfffe0000; ret >>= 16; ret |= ((insn & 0x20) >> 5); return ret;}static unsigned longinsert_i9 (insn, value, errmsg) unsigned long insn; signed long value; const char ** errmsg;{ if (value > 0xff || value < -0x100) * errmsg = _(immediate_out_of_range); return insn | ((value & 0x1e0) << 13) | (value & 0x1f);}static unsigned longextract_i9 (insn, invalid) unsigned long insn; int * invalid;{ signed long ret = insn & 0x003c0000; ret <<= 10; ret >>= 23; ret |= (insn & 0x1f); return ret;}static unsigned longinsert_u9 (insn, value, errmsg) unsigned long insn; unsigned long value; const char ** errmsg;{ if (value > 0x1ff) * errmsg = _(immediate_out_of_range); return insn | ((value & 0x1e0) << 13) | (value & 0x1f);}static unsigned longextract_u9 (insn, invalid) unsigned long insn; int * invalid;{ unsigned long ret = insn & 0x003c0000; ret >>= 13; ret |= (insn & 0x1f); return ret;}static unsigned longinsert_spe (insn, value, errmsg) unsigned long insn; unsigned long value; const char ** errmsg;{ if (value != 3) * errmsg = _("invalid register for stack adjustment"); return insn & (~ 0x180000);}static unsigned longextract_spe (insn, invalid) unsigned long insn; int * invalid;{ return 3;}static unsigned longinsert_i5div (insn, value, errmsg) unsigned long insn; unsigned long value; const char ** errmsg;{ if (value > 0x1ff) { if (value & 1) * errmsg = _("immediate value not in range and not even"); else * errmsg = _(immediate_out_of_range); } else if (value & 1) * errmsg = _("immediate value must be even"); value = 32 - value; return insn | ((value & 0x1e) << 17);}static unsigned longextract_i5div (insn, invalid) unsigned long insn; int * invalid;{ unsigned long ret = insn & 0x3c0000; ret >>= 17; ret = 32 - ret; return ret;}/* Warning: code in gas/config/tc-v850.c examines the contents of this array. If you change any of the values here, be sure to look for side effects in that code. */const struct v850_operand v850_operands[] ={#define UNUSED 0 { 0, 0, NULL, NULL, 0 }, /* The R1 field in a format 1, 6, 7, or 9 insn. */#define R1 (UNUSED + 1) { 5, 0, NULL, NULL, V850_OPERAND_REG }, /* As above, but register 0 is not allowed. */#define R1_NOTR0 (R1 + 1) { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 }, /* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */#define R2 (R1_NOTR0 + 1) { 5, 11, NULL, NULL, V850_OPERAND_REG },/* As above, but register 0 is not allowed. */#define R2_NOTR0 (R2 + 1) { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },/* The imm5 field in a format 2 insn. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?