6502/vasm/cpus/arm/cpu.h

215 lines
7.9 KiB
C

/* cpu.h ARM cpu-description header-file */
/* (c) in 2004,2014,2016 by Frank Wille */
#define LITTLEENDIAN (!arm_be_mode)
#define BIGENDIAN (arm_be_mode)
#define VASM_CPU_ARM 1
/* maximum number of operands in one mnemonic */
#define MAX_OPERANDS 6
/* maximum number of mnemonic-qualifiers per mnemonic */
#define MAX_QUALIFIERS 2
/* but no qualifiers for macros */
#define NO_MACRO_QUALIFIERS
/* valid parentheses for cpu's operands */
#define START_PARENTH(x) ((x)=='(' || (x)=='{')
#define END_PARENTH(x) ((x)==')' || (x)=='}')
/* data type to represent a target-address */
typedef int32_t taddr;
typedef uint32_t utaddr;
/* minimum instruction alignment */
#define INST_ALIGN 0 /* Handled internally! */
/* default alignment for n-bit data */
#define DATA_ALIGN(n) ((n)<=8 ? 1 : ((n)<=16 ? 2 : 4))
/* operand class for n-bit data definitions */
#define DATA_OPERAND(n) (n==64 ? DATA64_OP : DATA_OP)
/* returns true when instruction is valid for selected cpu */
#define MNEMONIC_VALID(i) cpu_available(i)
/* type to store each operand */
typedef struct {
uint16_t type; /* type of operand from mnemonic.operand_type */
uint16_t flags; /* see below */
expr *value; /* single register, immed. val. or branch loc.*/
} operand;
/* flags: */
#define OFL_SHIFTOP (0x0003) /* mask for shift-operation */
#define OFL_IMMEDSHIFT (0x0004) /* uses immediate shift value */
#define OFL_WBACK (0x0008) /* set write-back flag in opcode */
#define OFL_UP (0x0010) /* set up-flag, add offset to base */
#define OFL_SPSR (0x0020) /* 1:SPSR, 0:CPSR */
#define OFL_FORCE (0x0040) /* LDM/STM PSR & force user bit */
/* operand types - WARNING: the order is important! See defines below. */
enum {
/* ARM operands */
NOOP=0,
DATA_OP, /* data operand */
DATA64_OP, /* 64-bit data operand (greater than taddr) */
BRA24, /* 24-bit branch offset to label */
PCL12, /* 12-bit PC-relative offset with up/down-flag to label */
PCLCP, /* 8-bit * 4 PC-relative offset with up/down-flag to label */
PCLRT, /* 8-bit rotated PC-relative offset to label */
CPOP4, /* 4-bit coprocessor operation code at 23..20 */
CPOP3, /* 3-bit coprocessor operation code at 23..21 */
CPTYP, /* 3-bit coprocessor operation type at 7..5 */
SWI24, /* 24-bit immediate at 23..0 (SWI instruction) */
IROTV, /* explicit 4-bit rotate value at 11..8 */
REG03, /* Rn at 3..0 */
REG11, /* Rn at 11..8 */
REG15, /* Rn at 15..12 */
REG19, /* Rn at 19..16 */
R19WB, /* Rn at 19..16 with optional write-back '!' */
R19PR, /* [Rn, pre-indexed at 19..16 */
R19PO, /* [Rn], post-indexed or indir. without index, at 19..16 */
R3UD1, /* +/-Rn], pre-indexed at 3..0 with optional write-back '!' */
R3UD2, /* +/-Rn, at 3..0, pre- or post-indexed */
IMUD1, /* #+/-Imm12] pre-indexed with ']' and optional w-back '!' */
IMUD2, /* #+/-Imm12 post-indexed */
IMCP1, /* #+/-Imm10>>2 pre-indexed with ']' and optional w-back '!' */
IMCP2, /* #+/-Imm10>>2 post-indexed */
IMMD8, /* #Immediate, 8-bit */
IMROT, /* #Imm32, 8-bit auto-rotated */
SHIFT, /* <shift-op> Rs | <shift-op> #Imm5 | RRX = ROR #0 */
SHIM1, /* <shift-op> #Imm5 | RRX, pre-indexed with terminating ] or ]! */
SHIM2, /* <shift-op> #Imm5 | RRX, post-indexed */
CSPSR, /* CPSR or SPSR */
PSR_F, /* PSR-field: SPSR_<field>, CPSR_<field> */
RLIST, /* register list */
/* THUMB operands */
TRG02, /* Rn at 2..0 */
TRG05, /* Rn at 5..3 */
TRG08, /* Rn at 8..6 */
TRG10, /* Rn at 10..8 */
THR02, /* Hi-Rn at 2..0 */
THR05, /* Hi-Rn at 5..3 */
TR5IN, /* [Rn at 5..3 */
TR8IN, /* Rn] at 8..6 */
TR10W, /* Rn! at 10..8 with write-back '!' */
TPCRG, /* "PC" */
TSPRG, /* "SP" */
TPCPR, /* "[PC" */
TSPPR, /* "[SP" */
TRLST, /* register list for r0-r7 */
TRLLR, /* extended register list, includes LR */
TRLPC, /* extended register list, includes PC */
TUIM3, /* 3-bit unsigned immediate at 8..6 */
TUIM5, /* 5-bit unsigned immediate at 10..6 */
TUIM8, /* 8-bit unsigned immediate at 7..0 */
TUIM9, /* 9-bit unsigned immediate >> 2 at 6..0 */
TUIMA, /* 10-bit unsigned immediate >> 2 at 7..0 */
TUI5I, /* 5-bit unsigned immediate at 10..6 with terminating ] */
TUI6I, /* 6-bit unsigned immediate >> 1 at 10..6 with terminating ] */
TUI7I, /* 7-bit unsigned immediate >> 2 at 10..6 with terminating ] */
TUIAI, /* 10-bit unsigned immediate >> 2 at 7..0 with terminating ] */
TSWI8, /* 8-bit immediate at 7..0 (SWI instruction) */
TPCLW, /* PC-relative label, has to fit into 10-bit uns.imm. >> 2 */
TBR08, /* 9-bit branch offset >> 1 to label at 7..0 */
TBR11, /* 12-bit branch offset >> 1 to label at 10..0 */
TBRHL /* 23-bit branch offset >> 1 splitted into two 11-bit instr. */
};
#define ARMOPER(x) ((x)>=BRA24 && (x)<=RLIST)
#define STDOPER(x) ((x)>=DATA_OP && (x)<=IMROT)
#define CPOPCODE(x) ((x)>=CPOP4 && (x)<=CPTYP)
#define REGOPER(x) ((x)>=REG03 && (x)<=R3UD2)
#define REG19OPER(x) ((x)>=REG19 && (x)<=R19PO)
#define REG15OPER(x) ((x)==REG15)
#define REG11OPER(x) ((x)==REG11)
#define REG03OPER(x) ((x)==REG03 || (x)==R3UD1 || (x)==R3UD2)
#define UPDOWNOPER(x) ((x)>=R3UD1 && (x)<=IMCP2)
#define IMMEDOPER(x) ((x)>=IMUD1 && (x)<=IMROT)
#define SHIFTOPER(x) ((x)>=SHIFT && (x)<=SHIM2)
#define THUMBOPER(x) ((x)==0 || (x)>=TRG02)
#define THREGOPER(x) ((x)>=TRG02 && (x)<=TSPPR)
#define THPCORSP(x) ((x)>=TPCRG && (x)<=TSPPR)
#define THREGLIST(x) ((x)>=TRLST && (x)<=TRLPC)
#define THIMMOPER(x) ((x)>=TUIM3 && (x)<=TUIAI)
#define THIMMINDIR(x) ((x)>=TUI5I && (x)<=TUIAI)
#define THBRANCH(x) ((x)>=TBR08 && (x)<=TBRHL)
/* additional mnemonic data */
typedef struct {
uint32_t opcode;
uint32_t available;
uint32_t flags;
} mnemonic_extension;
/* flags: */
#define DIFR19 (0x00000001) /* DIFFRxx registers must be different */
#define DIFR15 (0x00000002)
#define DIFR11 (0x00000004)
#define DIFR03 (0x00000008)
#define NOPC (0x00000010) /* R15 is not allowed as source or dest. */
#define NOPCR03 (0x00000020) /* R15 is not allowed for Rm (3..0) */
#define NOPCWB (0x00000040) /* R15 is not allowed in Write-Back mode */
#define SETCC (0x00000100) /* instruction supports S-bit */
#define SETPSR (0x00000200) /* instruction supports P-bit */
#define THUMB (0x10000000) /* THUMB instruction */
/* register symbols */
#define HAVE_REGSYMS
#define REGSYMHTSIZE 256
/* cpu types for availability check */
#define ARM2 (1L<<0)
#define ARM250 (1L<<1)
#define ARM3 (1L<<2)
#define ARM6 (1L<<3)
#define ARM60 (1L<<4)
#define ARM600 (1L<<5)
#define ARM610 (1L<<6)
#define ARM7 (1L<<7)
#define ARM710 (1L<<8)
#define ARM7500 (1L<<9)
#define ARM7d (1L<<10)
#define ARM7di (1L<<11)
#define ARM7dm (1L<<12)
#define ARM7dmi (1L<<13)
#define ARM7tdmi (1L<<14)
#define ARM8 (1L<<15)
#define ARM810 (1L<<16)
#define ARM9 (1L<<17)
#define ARM920 (1L<<18)
#define ARM920t (1L<<19)
#define ARM9tdmi (1L<<20)
#define SA1 (1L<<21)
#define STRONGARM (1L<<22)
#define STRONGARM110 (1L<<23)
#define STRONGARM1100 (1L<<24)
/* ARM architectures */
#define AA2 (ARM2|ARM250|ARM3)
#define AA3 (ARM6|ARM60|ARM600|ARM610|ARM7|ARM710|ARM7500|ARM7d|ARM7di)
#define AA3M (ARM7dm|ARM7dmi)
#define AA4 (ARM8|ARM810|ARM9|ARM920|SA1|STRONGARM|STRONGARM110|STRONGARM1100)
#define AA4T (ARM7tdmi|ARM920t|ARM9tdmi)
#define AA4TUP (AA4T)
#define AA4UP (AA4|AA4T)
#define AA3MUP (AA3M|AA4|AA4T)
#define AA3UP (AA3|AA3M|AA4|AA4T)
#define AA2UP (AA2|AA3|AA3M|AA4|AA4T)
#define AAANY (~0)
/* exported by cpu.c */
extern int arm_be_mode;
int cpu_available(int);