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