| 1 | /* bfin-defs.h ADI Blackfin gas header file |
| 2 | Copyright 2005, 2006, 2007 |
| 3 | Free Software Foundation, Inc. |
| 4 | |
| 5 | This file is part of GAS, the GNU Assembler. |
| 6 | |
| 7 | GAS is free software; you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by |
| 9 | the Free Software Foundation; either version 3, or (at your option) |
| 10 | any later version. |
| 11 | |
| 12 | GAS is distributed in the hope that it will be useful, |
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | GNU General Public License for more details. |
| 16 | |
| 17 | You should have received a copy of the GNU General Public License |
| 18 | along with GAS; see the file COPYING. If not, write to the Free |
| 19 | Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA |
| 20 | 02110-1301, USA. */ |
| 21 | |
| 22 | #ifndef BFIN_PARSE_H |
| 23 | #define BFIN_PARSE_H |
| 24 | |
| 25 | #define PCREL 1 |
| 26 | #define CODE_FRAG_SIZE 4096 /* 1 page. */ |
| 27 | |
| 28 | |
| 29 | /* Definition for all status bits. */ |
| 30 | typedef enum |
| 31 | { |
| 32 | c_0, |
| 33 | c_1, |
| 34 | c_4, |
| 35 | c_2, |
| 36 | c_uimm2, |
| 37 | c_uimm3, |
| 38 | c_imm3, |
| 39 | c_pcrel4, |
| 40 | c_imm4, |
| 41 | c_uimm4s4, |
| 42 | c_uimm4, |
| 43 | c_uimm4s2, |
| 44 | c_negimm5s4, |
| 45 | c_imm5, |
| 46 | c_uimm5, |
| 47 | c_imm6, |
| 48 | c_imm7, |
| 49 | c_imm8, |
| 50 | c_uimm8, |
| 51 | c_pcrel8, |
| 52 | c_uimm8s4, |
| 53 | c_pcrel8s4, |
| 54 | c_lppcrel10, |
| 55 | c_pcrel10, |
| 56 | c_pcrel12, |
| 57 | c_imm16s4, |
| 58 | c_luimm16, |
| 59 | c_imm16, |
| 60 | c_huimm16, |
| 61 | c_rimm16, |
| 62 | c_imm16s2, |
| 63 | c_uimm16s4, |
| 64 | c_uimm16, |
| 65 | c_pcrel24 |
| 66 | } const_forms_t; |
| 67 | |
| 68 | |
| 69 | /* High-Nibble: group code, low nibble: register code. */ |
| 70 | |
| 71 | |
| 72 | #define T_REG_R 0x00 |
| 73 | #define T_REG_P 0x10 |
| 74 | #define T_REG_I 0x20 |
| 75 | #define T_REG_B 0x30 |
| 76 | #define T_REG_L 0x34 |
| 77 | #define T_REG_M 0x24 |
| 78 | #define T_REG_A 0x40 |
| 79 | |
| 80 | /* All registers above this value don't |
| 81 | belong to a usuable register group. */ |
| 82 | #define T_NOGROUP 0xa0 |
| 83 | |
| 84 | /* Flags. */ |
| 85 | #define F_REG_ALL 0x1000 |
| 86 | #define F_REG_HIGH 0x2000 /* Half register: high half. */ |
| 87 | |
| 88 | enum machine_registers |
| 89 | { |
| 90 | REG_R0 = T_REG_R, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, |
| 91 | REG_P0 = T_REG_P, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP, |
| 92 | REG_I0 = T_REG_I, REG_I1, REG_I2, REG_I3, |
| 93 | REG_M0 = T_REG_M, REG_M1, REG_M2, REG_M3, |
| 94 | REG_B0 = T_REG_B, REG_B1, REG_B2, REG_B3, |
| 95 | REG_L0 = T_REG_L, REG_L1, REG_L2, REG_L3, |
| 96 | REG_A0x = T_REG_A, REG_A0w, REG_A1x, REG_A1w, |
| 97 | REG_ASTAT = 0x46, |
| 98 | REG_RETS = 0x47, |
| 99 | REG_LC0 = 0x60, REG_LT0, REG_LB0, REG_LC1, REG_LT1, REG_LB1, |
| 100 | REG_CYCLES, REG_CYCLES2, |
| 101 | REG_USP = 0x70, REG_SEQSTAT, REG_SYSCFG, |
| 102 | REG_RETI, REG_RETX, REG_RETN, REG_RETE, REG_EMUDAT, |
| 103 | |
| 104 | /* These don't have groups. */ |
| 105 | REG_sftreset = T_NOGROUP, REG_omode, REG_excause, REG_emucause, |
| 106 | REG_idle_req, REG_hwerrcause, |
| 107 | REG_A0 = 0xc0, REG_A1, REG_CC, |
| 108 | /* Pseudo registers, used only for distinction from symbols. */ |
| 109 | REG_RL0, REG_RL1, REG_RL2, REG_RL3, |
| 110 | REG_RL4, REG_RL5, REG_RL6, REG_RL7, |
| 111 | REG_RH0, REG_RH1, REG_RH2, REG_RH3, |
| 112 | REG_RH4, REG_RH5, REG_RH6, REG_RH7, |
| 113 | REG_LASTREG |
| 114 | }; |
| 115 | |
| 116 | /* Status register flags. */ |
| 117 | |
| 118 | enum statusflags |
| 119 | { |
| 120 | S_AZ = 0, |
| 121 | S_AN, |
| 122 | S_AQ = 6, |
| 123 | S_AC0 = 12, |
| 124 | S_AC1, |
| 125 | S_AV0 = 16, |
| 126 | S_AV0S, |
| 127 | S_AV1, |
| 128 | S_AV1S, |
| 129 | S_V = 24, |
| 130 | S_VS = 25 |
| 131 | }; |
| 132 | |
| 133 | |
| 134 | enum reg_class |
| 135 | { |
| 136 | rc_dregs_lo, |
| 137 | rc_dregs_hi, |
| 138 | rc_dregs, |
| 139 | rc_dregs_pair, |
| 140 | rc_pregs, |
| 141 | rc_spfp, |
| 142 | rc_dregs_hilo, |
| 143 | rc_accum_ext, |
| 144 | rc_accum_word, |
| 145 | rc_accum, |
| 146 | rc_iregs, |
| 147 | rc_mregs, |
| 148 | rc_bregs, |
| 149 | rc_lregs, |
| 150 | rc_dpregs, |
| 151 | rc_gregs, |
| 152 | rc_regs, |
| 153 | rc_statbits, |
| 154 | rc_ignore_bits, |
| 155 | rc_ccstat, |
| 156 | rc_counters, |
| 157 | rc_dregs2_sysregs1, |
| 158 | rc_open, |
| 159 | rc_sysregs2, |
| 160 | rc_sysregs3, |
| 161 | rc_allregs, |
| 162 | LIM_REG_CLASSES |
| 163 | }; |
| 164 | |
| 165 | /* mmod field. */ |
| 166 | #define M_S2RND 1 |
| 167 | #define M_T 2 |
| 168 | #define M_W32 3 |
| 169 | #define M_FU 4 |
| 170 | #define M_TFU 6 |
| 171 | #define M_IS 8 |
| 172 | #define M_ISS2 9 |
| 173 | #define M_IH 11 |
| 174 | #define M_IU 12 |
| 175 | |
| 176 | /* Register type checking macros. */ |
| 177 | |
| 178 | #define CODE_MASK 0x07 |
| 179 | #define CLASS_MASK 0xf0 |
| 180 | |
| 181 | #define REG_SAME(a, b) ((a).regno == (b).regno) |
| 182 | #define REG_EQUAL(a, b) (((a).regno & CODE_MASK) == ((b).regno & CODE_MASK)) |
| 183 | #define REG_CLASS(a) ((a.regno) & 0xf0) |
| 184 | #define IS_A1(a) ((a).regno == REG_A1) |
| 185 | #define IS_H(a) ((a).regno & F_REG_HIGH ? 1: 0) |
| 186 | #define IS_EVEN(r) (r.regno % 2 == 0) |
| 187 | #define IS_HCOMPL(a, b) (REG_EQUAL(a, b) && \ |
| 188 | ((a).regno & F_REG_HIGH) != ((b).regno & F_REG_HIGH)) |
| 189 | |
| 190 | /* register type checking. */ |
| 191 | #define _TYPECHECK(r, x) (((r).regno & CLASS_MASK) == T_REG_##x) |
| 192 | |
| 193 | #define IS_DREG(r) _TYPECHECK(r, R) |
| 194 | #define IS_DREG_H(r) (_TYPECHECK(r, R) && IS_H(r)) |
| 195 | #define IS_DREG_L(r) (_TYPECHECK(r, R) && !IS_H(r)) |
| 196 | #define IS_PREG(r) _TYPECHECK(r, P) |
| 197 | #define IS_IREG(r) (((r).regno & 0xf4) == T_REG_I) |
| 198 | #define IS_MREG(r) (((r).regno & 0xf4) == T_REG_M) |
| 199 | #define IS_BREG(r) (((r).regno & 0xf4) == T_REG_B) |
| 200 | #define IS_LREG(r) (((r).regno & 0xf4) == T_REG_L) |
| 201 | #define IS_CREG(r) ((r).regno == REG_LC0 || (r).regno == REG_LC1) |
| 202 | #define IS_ALLREG(r) ((r).regno < T_NOGROUP) |
| 203 | |
| 204 | /* Expression value macros. */ |
| 205 | |
| 206 | typedef enum |
| 207 | { |
| 208 | ones_compl, |
| 209 | twos_compl, |
| 210 | mult, |
| 211 | divide, |
| 212 | mod, |
| 213 | add, |
| 214 | sub, |
| 215 | lsh, |
| 216 | rsh, |
| 217 | logand, |
| 218 | logior, |
| 219 | logxor |
| 220 | } expr_opcodes_t; |
| 221 | |
| 222 | struct expressionS; |
| 223 | |
| 224 | #define SYMBOL_T symbolS* |
| 225 | |
| 226 | struct expression_cell |
| 227 | { |
| 228 | int value; |
| 229 | SYMBOL_T symbol; |
| 230 | }; |
| 231 | |
| 232 | /* User Type Definitions. */ |
| 233 | struct bfin_insn |
| 234 | { |
| 235 | unsigned long value; |
| 236 | struct bfin_insn *next; |
| 237 | struct expression_cell *exp; |
| 238 | int pcrel; |
| 239 | int reloc; |
| 240 | }; |
| 241 | |
| 242 | #define INSTR_T struct bfin_insn* |
| 243 | #define EXPR_T struct expression_cell* |
| 244 | |
| 245 | typedef struct expr_node_struct Expr_Node; |
| 246 | |
| 247 | extern INSTR_T gencode (unsigned long x); |
| 248 | extern INSTR_T conscode (INSTR_T head, INSTR_T tail); |
| 249 | extern INSTR_T conctcode (INSTR_T head, INSTR_T tail); |
| 250 | extern INSTR_T note_reloc |
| 251 | (INSTR_T code, Expr_Node *, int reloc,int pcrel); |
| 252 | extern INSTR_T note_reloc1 |
| 253 | (INSTR_T code, const char * sym, int reloc, int pcrel); |
| 254 | extern INSTR_T note_reloc2 |
| 255 | (INSTR_T code, const char *symbol, int reloc, int value, int pcrel); |
| 256 | |
| 257 | /* Types of expressions. */ |
| 258 | typedef enum |
| 259 | { |
| 260 | Expr_Node_Binop, /* Binary operator. */ |
| 261 | Expr_Node_Unop, /* Unary operator. */ |
| 262 | Expr_Node_Reloc, /* Symbol to be relocated. */ |
| 263 | Expr_Node_GOT_Reloc, /* Symbol to be relocated using the GOT. */ |
| 264 | Expr_Node_Constant /* Constant. */ |
| 265 | } Expr_Node_Type; |
| 266 | |
| 267 | /* Types of operators. */ |
| 268 | typedef enum |
| 269 | { |
| 270 | Expr_Op_Type_Add, |
| 271 | Expr_Op_Type_Sub, |
| 272 | Expr_Op_Type_Mult, |
| 273 | Expr_Op_Type_Div, |
| 274 | Expr_Op_Type_Mod, |
| 275 | Expr_Op_Type_Lshift, |
| 276 | Expr_Op_Type_Rshift, |
| 277 | Expr_Op_Type_BAND, /* Bitwise AND. */ |
| 278 | Expr_Op_Type_BOR, /* Bitwise OR. */ |
| 279 | Expr_Op_Type_BXOR, /* Bitwise exclusive OR. */ |
| 280 | Expr_Op_Type_LAND, /* Logical AND. */ |
| 281 | Expr_Op_Type_LOR, /* Logical OR. */ |
| 282 | Expr_Op_Type_NEG, |
| 283 | Expr_Op_Type_COMP /* Complement. */ |
| 284 | } Expr_Op_Type; |
| 285 | |
| 286 | /* The value that can be stored ... depends on type. */ |
| 287 | typedef union |
| 288 | { |
| 289 | const char *s_value; /* if relocation symbol, the text. */ |
| 290 | int i_value; /* if constant, the value. */ |
| 291 | Expr_Op_Type op_value; /* if operator, the value. */ |
| 292 | } Expr_Node_Value; |
| 293 | |
| 294 | /* The expression node. */ |
| 295 | struct expr_node_struct |
| 296 | { |
| 297 | Expr_Node_Type type; |
| 298 | Expr_Node_Value value; |
| 299 | Expr_Node *Left_Child; |
| 300 | Expr_Node *Right_Child; |
| 301 | }; |
| 302 | |
| 303 | |
| 304 | /* Operations on the expression node. */ |
| 305 | Expr_Node *Expr_Node_Create (Expr_Node_Type type, |
| 306 | Expr_Node_Value value, |
| 307 | Expr_Node *Left_Child, |
| 308 | Expr_Node *Right_Child); |
| 309 | |
| 310 | /* Generate the reloc structure as a series of instructions. */ |
| 311 | INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc); |
| 312 | |
| 313 | #define MKREF(x) mkexpr (0,x) |
| 314 | #define ALLOCATE(x) malloc (x) |
| 315 | |
| 316 | #define NULL_CODE ((INSTR_T) 0) |
| 317 | |
| 318 | #ifndef EXPR_VALUE |
| 319 | #define EXPR_VALUE(x) (((x)->type == Expr_Node_Constant) ? ((x)->value.i_value) : 0) |
| 320 | #endif |
| 321 | #ifndef EXPR_SYMBOL |
| 322 | #define EXPR_SYMBOL(x) ((x)->symbol) |
| 323 | #endif |
| 324 | |
| 325 | |
| 326 | typedef long reg_t; |
| 327 | |
| 328 | |
| 329 | typedef struct _register |
| 330 | { |
| 331 | reg_t regno; /* Register ID as defined in machine_registers. */ |
| 332 | int flags; |
| 333 | } Register; |
| 334 | |
| 335 | |
| 336 | typedef struct _macfunc |
| 337 | { |
| 338 | char n; |
| 339 | char op; |
| 340 | char w; |
| 341 | char P; |
| 342 | Register dst; |
| 343 | Register s0; |
| 344 | Register s1; |
| 345 | } Macfunc; |
| 346 | |
| 347 | typedef struct _opt_mode |
| 348 | { |
| 349 | int MM; |
| 350 | int mod; |
| 351 | } Opt_mode; |
| 352 | |
| 353 | typedef enum |
| 354 | { |
| 355 | SEMANTIC_ERROR, |
| 356 | NO_INSN_GENERATED, |
| 357 | INSN_GENERATED |
| 358 | } parse_state; |
| 359 | |
| 360 | |
| 361 | #ifdef __cplusplus |
| 362 | extern "C" { |
| 363 | #endif |
| 364 | |
| 365 | extern int debug_codeselection; |
| 366 | |
| 367 | void error (char *format, ...); |
| 368 | void warn (char *format, ...); |
| 369 | int semantic_error (char *syntax); |
| 370 | void semantic_error_2 (char *syntax); |
| 371 | |
| 372 | EXPR_T mkexpr (int, SYMBOL_T); |
| 373 | |
| 374 | /* Defined in bfin-lex.l. */ |
| 375 | void set_start_state (void); |
| 376 | |
| 377 | #ifdef __cplusplus |
| 378 | } |
| 379 | #endif |
| 380 | |
| 381 | #endif /* BFIN_PARSE_H */ |
| 382 | |