Commit | Line | Data |
---|---|---|
07c1b327 CM |
1 | /* bfin-defs.h ADI Blackfin gas header file |
2 | Copyright 2005 | |
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 2, 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 | #include <bfd.h> | |
26 | #include "as.h" | |
27 | ||
28 | #define PCREL 1 | |
29 | #define CODE_FRAG_SIZE 4096 /* 1 page. */ | |
30 | ||
31 | ||
32 | /* Definition for all status bits. */ | |
33 | typedef enum | |
34 | { | |
35 | c_0, | |
36 | c_1, | |
37 | c_4, | |
38 | c_2, | |
39 | c_uimm2, | |
40 | c_uimm3, | |
41 | c_imm3, | |
42 | c_pcrel4, | |
43 | c_imm4, | |
44 | c_uimm4s4, | |
45 | c_uimm4, | |
46 | c_uimm4s2, | |
47 | c_negimm5s4, | |
48 | c_imm5, | |
49 | c_uimm5, | |
50 | c_imm6, | |
51 | c_imm7, | |
52 | c_imm8, | |
53 | c_uimm8, | |
54 | c_pcrel8, | |
55 | c_uimm8s4, | |
56 | c_pcrel8s4, | |
57 | c_lppcrel10, | |
58 | c_pcrel10, | |
59 | c_pcrel12, | |
60 | c_imm16s4, | |
61 | c_luimm16, | |
62 | c_imm16, | |
63 | c_huimm16, | |
64 | c_rimm16, | |
65 | c_imm16s2, | |
66 | c_uimm16s4, | |
67 | c_uimm16, | |
68 | c_pcrel24 | |
69 | } const_forms_t; | |
70 | ||
71 | ||
72 | /* High-Nibble: group code, low nibble: register code. */ | |
73 | ||
74 | ||
75 | #define T_REG_R 0x00 | |
76 | #define T_REG_P 0x10 | |
77 | #define T_REG_I 0x20 | |
78 | #define T_REG_B 0x30 | |
79 | #define T_REG_L 0x34 | |
80 | #define T_REG_M 0x24 | |
81 | #define T_REG_A 0x40 | |
82 | ||
83 | /* All registers above this value don't | |
84 | belong to a usuable register group. */ | |
85 | #define T_NOGROUP 0xa0 | |
86 | ||
87 | /* Flags. */ | |
88 | #define F_REG_ALL 0x1000 | |
89 | #define F_REG_HIGH 0x2000 /* Half register: high half. */ | |
90 | ||
91 | enum machine_registers | |
92 | { | |
93 | REG_R0 = T_REG_R, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, | |
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, | |
96 | REG_M0 = T_REG_M, REG_M1, REG_M2, REG_M3, | |
97 | REG_B0 = T_REG_B, REG_B1, REG_B2, REG_B3, | |
98 | REG_L0 = T_REG_L, REG_L1, REG_L2, REG_L3, | |
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, | |
105 | REG_RETI, REG_RETX, REG_RETN, REG_RETE, REG_EMUDAT, | |
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, | |
113 | REG_RL4, REG_RL5, REG_RL6, REG_RL7, | |
114 | REG_RH0, REG_RH1, REG_RH2, REG_RH3, | |
115 | REG_RH4, REG_RH5, REG_RH6, REG_RH7, | |
116 | REG_LASTREG | |
117 | }; | |
118 | ||
119 | /* Status register flags. */ | |
120 | ||
121 | enum statusflags | |
122 | { | |
123 | S_AZ = 0, | |
124 | S_AN, | |
125 | S_AQ = 6, | |
126 | S_AC0 = 12, | |
127 | S_AC1, | |
128 | S_AV0 = 16, | |
129 | S_AV0S, | |
130 | S_AV1, | |
131 | S_AV1S, | |
132 | S_V = 24, | |
133 | S_VS = 25 | |
134 | }; | |
135 | ||
136 | ||
137 | enum reg_class | |
138 | { | |
139 | rc_dregs_lo, | |
140 | rc_dregs_hi, | |
141 | rc_dregs, | |
142 | rc_dregs_pair, | |
143 | rc_pregs, | |
144 | rc_spfp, | |
145 | rc_dregs_hilo, | |
146 | rc_accum_ext, | |
147 | rc_accum_word, | |
148 | rc_accum, | |
149 | rc_iregs, | |
150 | rc_mregs, | |
151 | rc_bregs, | |
152 | rc_lregs, | |
153 | rc_dpregs, | |
154 | rc_gregs, | |
155 | rc_regs, | |
156 | rc_statbits, | |
157 | rc_ignore_bits, | |
158 | rc_ccstat, | |
159 | rc_counters, | |
160 | rc_dregs2_sysregs1, | |
161 | rc_open, | |
162 | rc_sysregs2, | |
163 | rc_sysregs3, | |
164 | rc_allregs, | |
165 | LIM_REG_CLASSES | |
166 | }; | |
167 | ||
168 | /* mmod field. */ | |
169 | #define M_S2RND 1 | |
170 | #define M_T 2 | |
171 | #define M_W32 3 | |
172 | #define M_FU 4 | |
173 | #define M_TFU 6 | |
174 | #define M_IS 8 | |
175 | #define M_ISS2 9 | |
176 | #define M_IH 11 | |
177 | #define M_IU 12 | |
178 | ||
179 | /* Register type checking macros. */ | |
180 | ||
181 | #define CODE_MASK 0x07 | |
182 | #define CLASS_MASK 0xf0 | |
183 | ||
184 | #define REG_SAME(a, b) ((a).regno == (b).regno) | |
185 | #define REG_EQUAL(a, b) (((a).regno & CODE_MASK) == ((b).regno & CODE_MASK)) | |
186 | #define REG_CLASS(a) ((a.regno) & 0xf0) | |
187 | #define IS_A1(a) ((a).regno == REG_A1) | |
188 | #define IS_H(a) ((a).regno & F_REG_HIGH ? 1: 0) | |
189 | #define IS_EVEN(r) (r.regno % 2 == 0) | |
190 | #define IS_HCOMPL(a, b) (REG_EQUAL(a, b) && \ | |
191 | ((a).regno & F_REG_HIGH) != ((b).regno & F_REG_HIGH)) | |
192 | ||
193 | /* register type checking. */ | |
194 | #define _TYPECHECK(r, x) (((r).regno & CLASS_MASK) == T_REG_##x) | |
195 | ||
196 | #define IS_DREG(r) _TYPECHECK(r, R) | |
197 | #define IS_DREG_H(r) (_TYPECHECK(r, R) && IS_H(r)) | |
198 | #define IS_DREG_L(r) (_TYPECHECK(r, R) && !IS_H(r)) | |
199 | #define IS_PREG(r) _TYPECHECK(r, P) | |
200 | #define IS_IREG(r) (((r).regno & 0xf4) == T_REG_I) | |
201 | #define IS_MREG(r) (((r).regno & 0xf4) == T_REG_M) | |
202 | #define IS_CREG(r) ((r).regno == REG_LC0 || (r).regno == REG_LC1) | |
203 | #define IS_ALLREG(r) ((r).regno < T_NOGROUP) | |
204 | ||
205 | /* Expression value macros. */ | |
206 | ||
207 | typedef enum | |
208 | { | |
209 | ones_compl, | |
210 | twos_compl, | |
211 | mult, | |
212 | divide, | |
213 | mod, | |
214 | add, | |
215 | sub, | |
216 | lsh, | |
217 | rsh, | |
218 | logand, | |
219 | logior, | |
220 | logxor | |
221 | } expr_opcodes_t; | |
222 | ||
223 | struct expressionS; | |
224 | ||
225 | #define SYMBOL_T symbolS* | |
226 | ||
227 | struct expression_cell | |
228 | { | |
229 | int value; | |
230 | SYMBOL_T symbol; | |
231 | }; | |
232 | ||
233 | /* User Type Definitions. */ | |
234 | struct bfin_insn | |
235 | { | |
236 | unsigned long value; | |
237 | struct bfin_insn *next; | |
238 | struct expression_cell *exp; | |
239 | int pcrel; | |
240 | int reloc; | |
241 | }; | |
242 | ||
243 | #define INSTR_T struct bfin_insn* | |
244 | #define EXPR_T struct expression_cell* | |
245 | ||
246 | typedef struct expr_node_struct Expr_Node; | |
247 | ||
248 | extern INSTR_T gencode (unsigned long x); | |
249 | extern INSTR_T conscode (INSTR_T head, INSTR_T tail); | |
250 | extern INSTR_T conctcode (INSTR_T head, INSTR_T tail); | |
251 | extern INSTR_T note_reloc | |
252 | (INSTR_T code, Expr_Node *, int reloc,int pcrel); | |
253 | extern INSTR_T note_reloc1 | |
254 | (INSTR_T code, const char * sym, int reloc, int pcrel); | |
255 | extern INSTR_T note_reloc2 | |
256 | (INSTR_T code, const char *symbol, int reloc, int value, int pcrel); | |
257 | ||
258 | /* Types of expressions. */ | |
259 | typedef enum | |
260 | { | |
261 | Expr_Node_Binop, /* Binary operator. */ | |
262 | Expr_Node_Unop, /* Unary operator. */ | |
263 | Expr_Node_Reloc, /* Symbol to be relocated. */ | |
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 | extern void bfin_equals (Expr_Node *sym); | |
375 | /* Defined in bfin-lex.l. */ | |
376 | void set_start_state (void); | |
377 | ||
378 | #ifdef __cplusplus | |
379 | } | |
380 | #endif | |
381 | ||
382 | #endif /* BFIN_PARSE_H */ | |
383 |