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