⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maverick.c

📁 俄罗斯高人Mamaich的Pocket gcc编译器(运行在PocketPC上)的全部源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2000 Free Software Foundation * Contributed by Alexandre Oliva <aoliva@cygnus.com> * * This file 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 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. *//* Generator of tests for Maverick. * * See the following file for usage and documentation.  */#include "../all/test-gen.c"/* These are the ARM registers.  Some of them have canonical names * other than r##, so we'll use both in the asm input, but only the * canonical names in the expected disassembler output.  */char *arm_regs[] = {  /* Canonical names.  */  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",  "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",  /* Alternate names, i.e., those that can be used in the assembler,   * but that will never be emitted by the disassembler.  */  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"};/* The various types of registers: ARM's registers, Maverick's * f/d/fx/dx registers, Maverick's accumulators and Maverick's status * register.  */#define armreg(shift) \  reg_r (arm_regs, shift, 0xf, mk_get_bits (5u))#define mvreg(prefix, shift) \  reg_p ("mv" prefix, shift, mk_get_bits (4u))#define acreg(shift) \  reg_p ("mvax", shift, mk_get_bits (2u))#define dspsc \  literal ("dspsc"), tick_random/* This outputs the condition flag that may follow each ARM insn. * Since the condition 15 is invalid, we use it to check that the * assembler recognizes the absence of a condition as `al'.  However, * the disassembler won't ever output `al', so, if we emit it in the * assembler, expect the condition to be omitted in the disassembler * output.  */intarm_cond (func_arg *arg, insn_data *data)#define arm_cond { arm_cond }{  static const char conds[16][3] = {    "eq", "ne", "cs", "cc",    "mi", "pl", "vs", "vc",    "hi", "ls", "ge", "lt",    "gt", "le", "al", ""  };  unsigned val = get_bits (4u);  data->as_in = data->dis_out = strdup (conds[val]);  if (val == 14)    data->dis_out = strdup ("");  data->bits = (val == 15 ? 14 : val) << 28;  return 0;}/* The sign of an offset is actually used to determined whether the * absolute value of the offset should be added or subtracted, so we * must adjust negative values so that they do not overflow: -256 is * not valid, but -0 is distinct from +0. */intoff8s (func_arg *arg, insn_data *data)#define off8s { off8s }{  int val = get_bits (9s);  char value[6], *strt = value;  *strt++ = '#';  if (val < 0)    {      *strt++ = '-';      ++val;      val = -val;      data->bits = val;    }  else    data->bits = val | (1 << 23);  sprintf (strt, "%i", val);  data->as_in = data->dis_out = strdup (value);  return 0;}/* This function generates a 7-bit signed constant, emitted as * follows: the 4 least-significant bits are stored in the 4 * least-significant bits of the word; the 3 most-significant bits are * stored in bits 7:5, i.e., bit 4 is skipped.  */intimm7 (func_arg *arg, insn_data *data)#define imm7 { imm7 }{  int val = get_bits (7s);  char value[6];  data->bits = (val & 0x0f) | (2 * (val & 0x70));  sprintf (value, "#%i", val);  data->as_in = data->dis_out = strdup (value);  return 0;}/* Convenience wrapper to define_insn, that prefixes every insn with * `cf' (so, if you specify command-line arguments, remember that `cf' * must *not* be part of the string), and post-fixes a condition code. * insname and insnvar specify the main insn name and a variant; * they're just concatenated, and insnvar is often empty.  word is the * bit pattern that defines the insn, properly shifted, and funcs is a * sequence of funcs that define the operands and the syntax of the * insn.  */#define mv_insn(insname, insnvar, word, funcs...) \  define_insn(insname ## insnvar, \	      literal ("cf"), \	      insn_bits (insname, word), \	      arm_cond, \	      tab, \	      ## funcs)/* Define a single LDC/STC variant.  op is the main insn opcode; ld * stands for load (it should be 0 on stores), dword selects 64-bit * operations, pre should be enabled for pre-increment, and wb, for * write-back.  sep1, sep2 and sep3 are syntactical elements ([]!) * that the assembler will use to enable pre and wb.  It would * probably have been cleaner to couple the syntactical elements with * the pre/wb bits directly, but it would have required the definition * of more functions.  */#define LDST(insname, insnvar, op, ld, dword, regname, pre, wb, sep1, sep2, sep3) \  mv_insn (insname, insnvar, \	   (12<<24)|(op<<8)|(ld<<20)|(pre<<24)|(dword<<22)|(wb<<21), \	    mvreg (regname, 12), comma, \	    lsqbkt, armreg (16), sep1, comma, off8s, sep2, sep3, \	    tick_random)/* Define all variants of an LDR or STR instruction, namely, * pre-indexed without write-back, pre-indexed with write-back and * post-indexed.  */#define LDSTall(insname, op, ld, dword, regname) \  LDST (insname, _p, op, ld, dword, regname, 1, 0, nothing, rsqbkt, nothing); \  LDST (insname, _pw, op, ld, dword, regname, 1, 1, nothing, rsqbkt, literal("!")); \  LDST (insname, ,op, ld, dword, regname, 0, 0, rsqbkt, nothing, nothing)/* Produce the insn identifiers of all LDST variants of a given insn. * To be used in the initialization of an insn group array.  */#define insns_LDSTall(insname) \  insn (insname ## _p), insn (insname ## _pw), insn (insname)/* Define a CDP variant that uses two registers, at offsets 12 and 16. * The two opcodes and the co-processor number identify the CDP * insn.  */#define CDP2(insname, var, cpnum, opcode1, opcode2, reg1name, reg2name) \  mv_insn (insname##var, , \	   (14<<24)|((opcode1)<<20)|((cpnum)<<8)|((opcode2)<<5), \	   mvreg (reg1name, 12), comma, mvreg (reg2name, 16))/* Define a 32-bit integer CDP instruction with two operands.  */#define CDP2fx(insname, opcode1, opcode2) \  CDP2 (insname, 32, 5, opcode1, opcode2, "fx", "fx")/* Define a 64-bit integer CDP instruction with two operands.  */#define CDP2dx(insname, opcode1, opcode2) \  CDP2 (insname, 64, 5, opcode1, opcode2, "dx", "dx")/* Define a float CDP instruction with two operands.  */#define CDP2f(insname, opcode1, opcode2) \  CDP2 (insname, s, 4, opcode1, opcode2, "f", "f")/* Define a double CDP instruction with two operands.  */#define CDP2d(insname, opcode1, opcode2) \  CDP2 (insname, d, 4, opcode1, opcode2, "d", "d")/* Define a CDP instruction with two register operands and one 7-bit * signed immediate generated with imm7.  */#define CDP2_imm7(insname, cpnum, opcode1, reg1name, reg2name) \  mv_insn (insname, , (14<<24)|((opcode1)<<20)|((cpnum)<<8), \	   mvreg (reg1name, 12), comma, mvreg (reg2name, 16), comma, imm7, \	   tick_random)/* Produce the insn identifiers of CDP floating-point or integer insn * pairs (i.e., it appends the suffixes for 32-bit and 64-bit * insns.  */#define CDPfp_insns(insname) \  insn (insname ## s), insn (insname ## d)#define CDPx_insns(insname) \  insn (insname ## 32), insn (insname ## 64)/* Define a CDP instruction with 3 operands, at offsets 12, 16, 0.  */#define CDP3(insname, var, cpnum, opcode1, opcode2, reg1name, reg2name, reg3name) \  mv_insn (insname##var, , \	   (14<<24)|((opcode1)<<20)|((cpnum)<<8)|((opcode2)<<5), \	   mvreg (reg1name, 12), comma, mvreg (reg2name, 16), comma, \	   mvreg (reg3name, 0), tick_random)/* Define a 32-bit integer CDP instruction with three operands.  */#define CDP3fx(insname, opcode1, opcode2) \  CDP3 (insname, 32, 5, opcode1, opcode2, "fx", "fx", "fx")/* Define a 64-bit integer CDP instruction with three operands.  */#define CDP3dx(insname, opcode1, opcode2) \  CDP3 (insname, 64, 5, opcode1, opcode2, "dx", "dx", "dx")/* Define a float CDP instruction with three operands.  */#define CDP3f(insname, opcode1, opcode2) \  CDP3 (insname, s, 4, opcode1, opcode2, "f", "f", "f")/* Define a double CDP instruction with three operands.  */#define CDP3d(insname, opcode1, opcode2) \  CDP3 (insname, d, 4, opcode1, opcode2, "d", "d", "d")/* Define a CDP instruction with four operands, at offsets 5, 12, 16 * and 0.  Used only for ACC instructions.  */#define CDP4(insname, opcode1, reg2spec, reg3name, reg4name) \  mv_insn (insname, , (14<<24)|((opcode1)<<20)|(6<<8), \	   acreg (5), comma, reg2spec, comma, \	   mvreg (reg3name, 16), comma, mvreg (reg4name, 0))/* Define a CDP4 instruction with one accumulator operands.  */#define CDP41A(insname, opcode1) \  CDP4 (insname, opcode1, mvreg ("fx", 12), "fx", "fx")/* Define a CDP4 instruction with two accumulator operands.  */#define CDP42A(insname, opcode1) \  CDP4 (insname, opcode1, acreg (12), "fx", "fx")/* Define a MCR or MRC instruction with two register operands.  */#define MCRC2(insname, cpnum, opcode1, dir, opcode2, reg1spec, reg2spec) \  mv_insn (insname, , \	   ((14<<24)|((opcode1)<<21)|((dir)<<20)| \	    ((cpnum)<<8)|((opcode2)<<5)|(1<<4)), \	   reg1spec, comma, reg2spec)/* Define a move from a DSP register to an ARM register.  */#define MVDSPARM(insname, cpnum, opcode2, regDSPname) \  MCRC2 (mv ## insname, cpnum, 0, 0, opcode2, \	 mvreg (regDSPname, 16), armreg(12))/* Define a move from an ARM register to a DSP register.  */#define MVARMDSP(insname, cpnum, opcode2, regDSPname) \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -