1 /* 2 * Copyright (c) 2007-2009 Dominic Morris <dom /at/ suborbital.org.uk> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 /* z80 backend for vasm */ 27 28 #include <stdint.h> 29 30 #define BIGENDIAN 0 31 #define LITTLEENDIAN 1 32 #define VASM_CPU_Z80 1 33 34 /* maximum number of operands for one mnemonic */ 35 #define MAX_OPERANDS 2 36 37 /* maximum number of mnemonic-qualifiers per mnemonic */ 38 #define MAX_QUALIFIERS 0 39 40 /* maximum number of additional command-line-flags for this cpu */ 41 42 /* data type to represent a target-address */ 43 typedef int32_t taddr; 44 typedef uint32_t utaddr; 45 46 #define HAVE_INSTRUCTION_EXTENSION 1 47 typedef struct { 48 int altd; 49 int ioi; 50 int ioe; 51 } instruction_ext; 52 53 /* minimum instruction alignment */ 54 #define INST_ALIGN 1 55 56 /* default alignment for n-bit data */ 57 #define DATA_ALIGN(n) 1 58 59 /* operand class for n-bit data definitions */ 60 #define DATA_OPERAND(n) OP_DATA 61 62 /* we define two additional unary operations, '<' and '>' */ 63 int ext_unary_eval(int,taddr,taddr *,int); 64 int ext_find_base(symbol **,expr *,section *,taddr); 65 #define LOBYTE (LAST_EXP_TYPE+1) 66 #define HIBYTE (LAST_EXP_TYPE+2) 67 #define EXT_UNARY_NAME(s) (*s=='<'||*s=='>') 68 #define EXT_UNARY_TYPE(s) (*s=='<'?LOBYTE:HIBYTE) 69 #define EXT_UNARY_EVAL(t,v,r,c) ext_unary_eval(t,v,r,c) 70 #define EXT_FIND_BASE(b,e,s,p) ext_find_base(b,e,s,p) 71 72 /* Z80 allows ':' as a statement delimiter in oldstyle-syntax */ 73 #define STATEMENT_DELIMITER ':' 74 75 76 /* type to store each operand */ 77 typedef struct { 78 int reg; 79 int type; 80 int flags; 81 int bit; 82 expr *value; 83 } operand; 84 85 86 #define CPU_8080 1 87 #define CPU_Z80 2 88 #define CPU_RCM2000 4 89 #define CPU_RCM3000 8 90 #define CPU_RCM4000 16 91 #define CPU_Z180 32 92 #define CPU_EZ80 64 93 #define CPU_GB80 128 94 95 96 #define CPU_RABBIT (CPU_RCM2000|CPU_RCM3000|CPU_RCM4000) 97 #define CPU_ZILOG (CPU_Z80|CPU_Z180|CPU_EZ80) 98 #define CPU_ALL ( CPU_ZILOG | CPU_8080 | CPU_RABBIT | CPU_GB80 ) 99 #define CPU_NOT8080 ( CPU_ALL ^ CPU_8080 ) 100 #define CPU_NOTGB80 ( CPU_ALL ^ CPU_GB80 ) 101 102 #define RCM_EMU_NONE 0 103 #define RCM_EMU_INCREMENT 1 /* Move to next instruction */ 104 #define RCM_EMU_LIBRARY 2 /* Call a library routine */ 105 106 /* Flags for altd */ 107 #define F_IO 1 /* ioe/ioi valid */ 108 #define F_ALTD 2 /* altd valid */ 109 #define F_ALTDW 4 /* warn about altw use */ 110 #define F_ALTDWHL 8 /* Warn about HLREF use with altd */ 111 112 #define F_ALL ( F_IO|F_ALTD) 113 114 /* additional mnemonic data */ 115 typedef struct { 116 int mode; /* Opcode mode */ 117 uint32_t opcode; /* Opcode */ 118 unsigned char cpus; 119 int modifier_flags; /* Modifier flags for altd/ioi etc */ 120 int rabbit2000_action; /* Action to take on a rabbit */ 121 int rabbit3000_action; /* Action to take on a rabbit */ 122 int rabbit4000_action; /* Action to take on a rabbit */ 123 int gb80_action; /* Action to take for a GBz80 */ 124 } mnemonic_extension; 125 126 /* These values are significant - opcodes derived using them */ 127 #define FLAGS_NZ 0 128 #define FLAGS_Z 1 129 #define FLAGS_NC 2 130 #define FLAGS_C 3 131 #define FLAGS_PO 4 132 #define FLAGS_PE 5 133 #define FLAGS_P 6 134 #define FLAGS_M 7 135 136 /* These values are significant - RCM4000 flags */ 137 #define FLAGS_GT 0 138 #define FLAGS_GTU 1 139 #define FLAGS_LT 2 140 #define FLAGS_V 3 141 142 /* Theses values are significant */ 143 #define REG_BC 0x00 144 #define REG_DE 0x01 145 #define REG_HL 0x02 146 #define REG_SP 0x03 147 #define REG_AF 0x04 148 149 150 /* These values are signifcant - opcodes are derived using them */ 151 #define REG_B 0x00 152 #define REG_C 0x01 153 #define REG_D 0x02 154 #define REG_E 0x03 155 #define REG_H 0x04 156 #define REG_L 0x05 157 #define REG_HLREF 0x06 158 #define REG_A 0x07 159 /* Extra ones - values from here onwards aren't significant */ 160 #define REG_I 0x08 161 #define REG_R 0x09 162 #define REG_F 0x0a 163 #define REG_PORT 0x0b 164 /* Rabbit extras */ 165 #define REG_IP 0x0c 166 #define REG_XPC 0x0d 167 /* Rabbit 4000 extras */ 168 #define REG_JK 0x0d 169 #define REG_BCDE 0x0e 170 #define REG_JKHL 0x0f 171 /* PW...PZ should be defined in this order */ 172 #define REG_PW 0x10 173 #define REG_PX 0x11 174 #define REG_PY 0x12 175 #define REG_PZ 0x13 176 #define REG_SU 0x14 177 #define REG_HTR 0x15 178 179 #define REG_PLAIN 0x1f /* Mask to get the register out */ 180 181 /* Modifiers */ 182 #define REG_IX 0x20 /* h,l modified by ix */ 183 #define REG_IY 0x40 /* h,l modified by iy */ 184 #define REG_ALT 0x80 /* alternate registers */ 185 #define REG_INDEX 0x100 /* (ix + ) */ 186 187 188 189 190 191 192 /* Operand types */ 193 #define OP_NONE 0x00 194 #define OP_ABS 0x01 195 #define OP_ABS16 0x02 196 #define OP_REG16 0x03 197 #define OP_REG8 0x04 198 #define OP_AF 0x05 /* af */ 199 #define OP_SP 0x06 /* sp */ 200 #define OP_HL 0x07 /* hl */ 201 #define OP_DE 0x08 /* de */ 202 #define OP_BC 0x09 /* bc */ 203 #define OP_JK 0x0a 204 #define OP_BCDE 0x0b 205 #define OP_JKHL 0x0c 206 #define OP_A 0x0d /* a register */ 207 #define OP_R 0x0e /* r register */ 208 #define OP_I 0x0f /* i register */ 209 #define OP_F 0x10 /* f - for in f,(c) */ 210 #define OP_PORT 0x11 211 #define OP_FLAGS 0x12 /* nz, z, nc, c, (po, pe) */ 212 #define OP_FLAGS_RCM 0x13 /* gt, lt, ge, le */ 213 #define OP_ADDR 0x14 /* (xx) - an address */ 214 #define OP_NUMBER 0x15 /* for bit, im, res, set, rst */ 215 #define OP_ADDR8 0x16 216 #define OP_IP 0x17 /* ip (RCM) */ 217 #define OP_XPC 0x18 218 #define OP_ABS24 0x19 219 #define OP_ABS32 0x20 220 #define OP_ADDR24 0x21 221 #define OP_ADDR32 0x22 222 #define OP_IX 0x23 223 #define OP_IY 0x24 224 #define OP_IDX32 0x25 225 #define OP_SU 0x26 226 #define OP_HTR 0x27 227 #define OP_DATA 0x3e 228 229 #define OP_MASK 0x3f /* Gets the basic operation out */ 230 231 /* Modifiers */ 232 #define OP_INDIR 0x40 /* ( x ) */ 233 #define OP_INDEX 0x80 /* Modifier for 8 bit operations with ixh, ixl */ 234 #define OP_ALT 0x100 235 #define OP_OFFSET 0x200 /* Has an offset as well (always optional) - maybe from ix,iy or sp,hl (rabbit) */ 236 #define OP_ARITH16 0x400 237 #define OP_PUSHABLE 0x800 238 #define OP_STD16BIT 0x1000 239 #define OP_RALT 0x2000 /* Accept an alt register on a rabbit (only used mnemonics) - except (hl) */ 240 #define OP_RALTHL 0x4000 /* Accept an alt (hl) register on a rabbit (only used mnemonics) */ 241 #define OP_OFFSA 0x8000 /* Have +a as offset */ 242 #define OP_OFFSHL 0x10000 /* Have +hl as offset */ 243 #define OP_OFFSBC 0x20000 /* Have +bc as offset */ 244 #define OP_OFFSDE 0x40000 /* Have +de as offset */ 245 #define OP_OFFSIX 0x80000 /* Have +ix as offset */ 246 #define OP_OFFSIY 0x100000 /* Have +iy as offset */ 247 248 249 250 /* Opcode types - we can group them together to calculate offsets etc */ 251 #define TYPE_NONE 0x00 /* No modifiers */ 252 #define TYPE_ARITH8 0x01 /* + reg1 index or + reg2 index*/ 253 #define TYPE_MISC8 0x02 /* + reg1 * 8 or + reg 2 * 8*/ 254 #define TYPE_LD8 0x03 /* + reg1 * 8 + reg 2 */ 255 #define TYPE_ARITH16 0x04 /* reg * 16 */ 256 257 #define TYPE_FLAGS 0x05 /* flags * 8 */ 258 #define TYPE_RELJUMP 0x06 /* jr/djnz/jre (flags *8 if necessary */ 259 260 #define TYPE_BIT 0x07 /* Bit setting etc */ 261 #define TYPE_RST 0x08 /* rst XX */ 262 #define TYPE_IM 0x09 /* im */ 263 #define TYPE_EDPREF 0x0a /* Has a 0xed prefix by default (RCM opcodes) */ 264 #define TYPE_IPSET 0x0b /* ipset X (RCM) */ 265 #define TYPE_IDX32 0x0c /* p? * 16 */ 266 #define TYPE_NOPREFIX 0x0d /* Don't add on an indexing prefix (RCM) */ 267 #define TYPE_IDX32R 0x0e /* p? * 16 + p? * 64*/ 268 #define TYPE_OUT_C_0 0x0f /* for out (c), number, number can only be 0 */ 269