| 1 | /* CPU family header for lm32bf. |
| 2 | |
| 3 | THIS FILE IS MACHINE GENERATED WITH CGEN. |
| 4 | |
| 5 | Copyright 1996-2010 Free Software Foundation, Inc. |
| 6 | |
| 7 | This file is part of the GNU simulators. |
| 8 | |
| 9 | This file is free software; you can redistribute it and/or modify |
| 10 | it under the terms of the GNU General Public License as published by |
| 11 | the Free Software Foundation; either version 3, or (at your option) |
| 12 | any later version. |
| 13 | |
| 14 | It is distributed in the hope that it will be useful, but WITHOUT |
| 15 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
| 16 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
| 17 | License for more details. |
| 18 | |
| 19 | You should have received a copy of the GNU General Public License along |
| 20 | with this program; if not, write to the Free Software Foundation, Inc., |
| 21 | 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
| 22 | |
| 23 | */ |
| 24 | |
| 25 | #ifndef CPU_LM32BF_H |
| 26 | #define CPU_LM32BF_H |
| 27 | |
| 28 | /* Maximum number of instructions that are fetched at a time. |
| 29 | This is for LIW type instructions sets (e.g. m32r). */ |
| 30 | #define MAX_LIW_INSNS 1 |
| 31 | |
| 32 | /* Maximum number of instructions that can be executed in parallel. */ |
| 33 | #define MAX_PARALLEL_INSNS 1 |
| 34 | |
| 35 | /* The size of an "int" needed to hold an instruction word. |
| 36 | This is usually 32 bits, but some architectures needs 64 bits. */ |
| 37 | typedef CGEN_INSN_INT CGEN_INSN_WORD; |
| 38 | |
| 39 | #include "cgen-engine.h" |
| 40 | |
| 41 | /* CPU state information. */ |
| 42 | typedef struct { |
| 43 | /* Hardware elements. */ |
| 44 | struct { |
| 45 | /* Program counter */ |
| 46 | USI h_pc; |
| 47 | #define GET_H_PC() CPU (h_pc) |
| 48 | #define SET_H_PC(x) (CPU (h_pc) = (x)) |
| 49 | /* General purpose registers */ |
| 50 | SI h_gr[32]; |
| 51 | #define GET_H_GR(a1) CPU (h_gr)[a1] |
| 52 | #define SET_H_GR(a1, x) (CPU (h_gr)[a1] = (x)) |
| 53 | /* Control and status registers */ |
| 54 | SI h_csr[32]; |
| 55 | #define GET_H_CSR(a1) CPU (h_csr)[a1] |
| 56 | #define SET_H_CSR(a1, x) (CPU (h_csr)[a1] = (x)) |
| 57 | } hardware; |
| 58 | #define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware) |
| 59 | } LM32BF_CPU_DATA; |
| 60 | |
| 61 | /* Cover fns for register access. */ |
| 62 | USI lm32bf_h_pc_get (SIM_CPU *); |
| 63 | void lm32bf_h_pc_set (SIM_CPU *, USI); |
| 64 | SI lm32bf_h_gr_get (SIM_CPU *, UINT); |
| 65 | void lm32bf_h_gr_set (SIM_CPU *, UINT, SI); |
| 66 | SI lm32bf_h_csr_get (SIM_CPU *, UINT); |
| 67 | void lm32bf_h_csr_set (SIM_CPU *, UINT, SI); |
| 68 | |
| 69 | /* These must be hand-written. */ |
| 70 | extern CPUREG_FETCH_FN lm32bf_fetch_register; |
| 71 | extern CPUREG_STORE_FN lm32bf_store_register; |
| 72 | |
| 73 | typedef struct { |
| 74 | int empty; |
| 75 | } MODEL_LM32_DATA; |
| 76 | |
| 77 | /* Instruction argument buffer. */ |
| 78 | |
| 79 | union sem_fields { |
| 80 | struct { /* no operands */ |
| 81 | int empty; |
| 82 | } sfmt_empty; |
| 83 | struct { /* */ |
| 84 | IADDR i_call; |
| 85 | } sfmt_bi; |
| 86 | struct { /* */ |
| 87 | UINT f_csr; |
| 88 | UINT f_r1; |
| 89 | } sfmt_wcsr; |
| 90 | struct { /* */ |
| 91 | UINT f_csr; |
| 92 | UINT f_r2; |
| 93 | } sfmt_rcsr; |
| 94 | struct { /* */ |
| 95 | IADDR i_branch; |
| 96 | UINT f_r0; |
| 97 | UINT f_r1; |
| 98 | } sfmt_be; |
| 99 | struct { /* */ |
| 100 | UINT f_r0; |
| 101 | UINT f_r1; |
| 102 | UINT f_uimm; |
| 103 | } sfmt_andi; |
| 104 | struct { /* */ |
| 105 | INT f_imm; |
| 106 | UINT f_r0; |
| 107 | UINT f_r1; |
| 108 | } sfmt_addi; |
| 109 | struct { /* */ |
| 110 | UINT f_r0; |
| 111 | UINT f_r1; |
| 112 | UINT f_r2; |
| 113 | UINT f_user; |
| 114 | } sfmt_user; |
| 115 | #if WITH_SCACHE_PBB |
| 116 | /* Writeback handler. */ |
| 117 | struct { |
| 118 | /* Pointer to argbuf entry for insn whose results need writing back. */ |
| 119 | const struct argbuf *abuf; |
| 120 | } write; |
| 121 | /* x-before handler */ |
| 122 | struct { |
| 123 | /*const SCACHE *insns[MAX_PARALLEL_INSNS];*/ |
| 124 | int first_p; |
| 125 | } before; |
| 126 | /* x-after handler */ |
| 127 | struct { |
| 128 | int empty; |
| 129 | } after; |
| 130 | /* This entry is used to terminate each pbb. */ |
| 131 | struct { |
| 132 | /* Number of insns in pbb. */ |
| 133 | int insn_count; |
| 134 | /* Next pbb to execute. */ |
| 135 | SCACHE *next; |
| 136 | SCACHE *branch_target; |
| 137 | } chain; |
| 138 | #endif |
| 139 | }; |
| 140 | |
| 141 | /* The ARGBUF struct. */ |
| 142 | struct argbuf { |
| 143 | /* These are the baseclass definitions. */ |
| 144 | IADDR addr; |
| 145 | const IDESC *idesc; |
| 146 | char trace_p; |
| 147 | char profile_p; |
| 148 | /* ??? Temporary hack for skip insns. */ |
| 149 | char skip_count; |
| 150 | char unused; |
| 151 | /* cpu specific data follows */ |
| 152 | union sem semantic; |
| 153 | int written; |
| 154 | union sem_fields fields; |
| 155 | }; |
| 156 | |
| 157 | /* A cached insn. |
| 158 | |
| 159 | ??? SCACHE used to contain more than just argbuf. We could delete the |
| 160 | type entirely and always just use ARGBUF, but for future concerns and as |
| 161 | a level of abstraction it is left in. */ |
| 162 | |
| 163 | struct scache { |
| 164 | struct argbuf argbuf; |
| 165 | }; |
| 166 | |
| 167 | /* Macros to simplify extraction, reading and semantic code. |
| 168 | These define and assign the local vars that contain the insn's fields. */ |
| 169 | |
| 170 | #define EXTRACT_IFMT_EMPTY_VARS \ |
| 171 | unsigned int length; |
| 172 | #define EXTRACT_IFMT_EMPTY_CODE \ |
| 173 | length = 0; \ |
| 174 | |
| 175 | #define EXTRACT_IFMT_ADD_VARS \ |
| 176 | UINT f_opcode; \ |
| 177 | UINT f_r0; \ |
| 178 | UINT f_r1; \ |
| 179 | UINT f_r2; \ |
| 180 | UINT f_resv0; \ |
| 181 | unsigned int length; |
| 182 | #define EXTRACT_IFMT_ADD_CODE \ |
| 183 | length = 4; \ |
| 184 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 185 | f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 186 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 187 | f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \ |
| 188 | f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \ |
| 189 | |
| 190 | #define EXTRACT_IFMT_ADDI_VARS \ |
| 191 | UINT f_opcode; \ |
| 192 | UINT f_r0; \ |
| 193 | UINT f_r1; \ |
| 194 | INT f_imm; \ |
| 195 | unsigned int length; |
| 196 | #define EXTRACT_IFMT_ADDI_CODE \ |
| 197 | length = 4; \ |
| 198 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 199 | f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 200 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 201 | f_imm = EXTRACT_LSB0_SINT (insn, 32, 15, 16); \ |
| 202 | |
| 203 | #define EXTRACT_IFMT_ANDI_VARS \ |
| 204 | UINT f_opcode; \ |
| 205 | UINT f_r0; \ |
| 206 | UINT f_r1; \ |
| 207 | UINT f_uimm; \ |
| 208 | unsigned int length; |
| 209 | #define EXTRACT_IFMT_ANDI_CODE \ |
| 210 | length = 4; \ |
| 211 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 212 | f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 213 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 214 | f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16); \ |
| 215 | |
| 216 | #define EXTRACT_IFMT_ANDHII_VARS \ |
| 217 | UINT f_opcode; \ |
| 218 | UINT f_r0; \ |
| 219 | UINT f_r1; \ |
| 220 | UINT f_uimm; \ |
| 221 | unsigned int length; |
| 222 | #define EXTRACT_IFMT_ANDHII_CODE \ |
| 223 | length = 4; \ |
| 224 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 225 | f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 226 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 227 | f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16); \ |
| 228 | |
| 229 | #define EXTRACT_IFMT_B_VARS \ |
| 230 | UINT f_opcode; \ |
| 231 | UINT f_r0; \ |
| 232 | UINT f_r1; \ |
| 233 | UINT f_r2; \ |
| 234 | UINT f_resv0; \ |
| 235 | unsigned int length; |
| 236 | #define EXTRACT_IFMT_B_CODE \ |
| 237 | length = 4; \ |
| 238 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 239 | f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 240 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 241 | f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \ |
| 242 | f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \ |
| 243 | |
| 244 | #define EXTRACT_IFMT_BI_VARS \ |
| 245 | UINT f_opcode; \ |
| 246 | SI f_call; \ |
| 247 | unsigned int length; |
| 248 | #define EXTRACT_IFMT_BI_CODE \ |
| 249 | length = 4; \ |
| 250 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 251 | f_call = ((pc) + (((SI) (((EXTRACT_LSB0_SINT (insn, 32, 25, 26)) << (6))) >> (4)))); \ |
| 252 | |
| 253 | #define EXTRACT_IFMT_BE_VARS \ |
| 254 | UINT f_opcode; \ |
| 255 | UINT f_r0; \ |
| 256 | UINT f_r1; \ |
| 257 | SI f_branch; \ |
| 258 | unsigned int length; |
| 259 | #define EXTRACT_IFMT_BE_CODE \ |
| 260 | length = 4; \ |
| 261 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 262 | f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 263 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 264 | f_branch = ((pc) + (((SI) (((EXTRACT_LSB0_SINT (insn, 32, 15, 16)) << (16))) >> (14)))); \ |
| 265 | |
| 266 | #define EXTRACT_IFMT_ORI_VARS \ |
| 267 | UINT f_opcode; \ |
| 268 | UINT f_r0; \ |
| 269 | UINT f_r1; \ |
| 270 | UINT f_uimm; \ |
| 271 | unsigned int length; |
| 272 | #define EXTRACT_IFMT_ORI_CODE \ |
| 273 | length = 4; \ |
| 274 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 275 | f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 276 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 277 | f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16); \ |
| 278 | |
| 279 | #define EXTRACT_IFMT_RCSR_VARS \ |
| 280 | UINT f_opcode; \ |
| 281 | UINT f_csr; \ |
| 282 | UINT f_r1; \ |
| 283 | UINT f_r2; \ |
| 284 | UINT f_resv0; \ |
| 285 | unsigned int length; |
| 286 | #define EXTRACT_IFMT_RCSR_CODE \ |
| 287 | length = 4; \ |
| 288 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 289 | f_csr = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 290 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 291 | f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \ |
| 292 | f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \ |
| 293 | |
| 294 | #define EXTRACT_IFMT_SEXTB_VARS \ |
| 295 | UINT f_opcode; \ |
| 296 | UINT f_r0; \ |
| 297 | UINT f_r1; \ |
| 298 | UINT f_r2; \ |
| 299 | UINT f_resv0; \ |
| 300 | unsigned int length; |
| 301 | #define EXTRACT_IFMT_SEXTB_CODE \ |
| 302 | length = 4; \ |
| 303 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 304 | f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 305 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 306 | f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \ |
| 307 | f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \ |
| 308 | |
| 309 | #define EXTRACT_IFMT_USER_VARS \ |
| 310 | UINT f_opcode; \ |
| 311 | UINT f_r0; \ |
| 312 | UINT f_r1; \ |
| 313 | UINT f_r2; \ |
| 314 | UINT f_user; \ |
| 315 | unsigned int length; |
| 316 | #define EXTRACT_IFMT_USER_CODE \ |
| 317 | length = 4; \ |
| 318 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 319 | f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 320 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 321 | f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \ |
| 322 | f_user = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \ |
| 323 | |
| 324 | #define EXTRACT_IFMT_WCSR_VARS \ |
| 325 | UINT f_opcode; \ |
| 326 | UINT f_csr; \ |
| 327 | UINT f_r1; \ |
| 328 | UINT f_r2; \ |
| 329 | UINT f_resv0; \ |
| 330 | unsigned int length; |
| 331 | #define EXTRACT_IFMT_WCSR_CODE \ |
| 332 | length = 4; \ |
| 333 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 334 | f_csr = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \ |
| 335 | f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \ |
| 336 | f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \ |
| 337 | f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \ |
| 338 | |
| 339 | #define EXTRACT_IFMT_BREAK_VARS \ |
| 340 | UINT f_opcode; \ |
| 341 | UINT f_exception; \ |
| 342 | unsigned int length; |
| 343 | #define EXTRACT_IFMT_BREAK_CODE \ |
| 344 | length = 4; \ |
| 345 | f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \ |
| 346 | f_exception = EXTRACT_LSB0_UINT (insn, 32, 25, 26); \ |
| 347 | |
| 348 | /* Collection of various things for the trace handler to use. */ |
| 349 | |
| 350 | typedef struct trace_record { |
| 351 | IADDR pc; |
| 352 | /* FIXME:wip */ |
| 353 | } TRACE_RECORD; |
| 354 | |
| 355 | #endif /* CPU_LM32BF_H */ |