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