02110-1301, USA. */
#ifndef BFIN_PARSE_H
-#define BFIN_PARSE_H
+#define BFIN_PARSE_H
#define PCREL 1
-#define CODE_FRAG_SIZE 4096 /* 1 page. */
+#define CODE_FRAG_SIZE 4096 /* 1 page. */
/* Definition for all status bits. */
c_uimm2,
c_uimm3,
c_imm3,
- c_pcrel4,
+ c_pcrel4,
c_imm4,
c_uimm4s4,
c_uimm4,
c_negimm5s4,
c_imm5,
c_uimm5,
- c_imm6,
+ c_imm6,
c_imm7,
c_imm8,
c_uimm8,
c_uimm8s4,
c_pcrel8s4,
c_lppcrel10,
- c_pcrel10,
+ c_pcrel10,
c_pcrel12,
c_imm16s4,
c_luimm16,
c_huimm16,
c_rimm16,
c_imm16s2,
- c_uimm16s4,
+ c_uimm16s4,
c_uimm16,
- c_pcrel24
+ c_pcrel24
} const_forms_t;
enum machine_registers
{
- REG_R0 = T_REG_R, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
+ REG_R0 = T_REG_R, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
REG_P0 = T_REG_P, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
REG_I0 = T_REG_I, REG_I1, REG_I2, REG_I3,
- REG_M0 = T_REG_M, REG_M1, REG_M2, REG_M3,
+ REG_M0 = T_REG_M, REG_M1, REG_M2, REG_M3,
REG_B0 = T_REG_B, REG_B1, REG_B2, REG_B3,
- REG_L0 = T_REG_L, REG_L1, REG_L2, REG_L3,
+ REG_L0 = T_REG_L, REG_L1, REG_L2, REG_L3,
REG_A0x = T_REG_A, REG_A0w, REG_A1x, REG_A1w,
REG_ASTAT = 0x46,
REG_RETS = 0x47,
REG_LC0 = 0x60, REG_LT0, REG_LB0, REG_LC1, REG_LT1, REG_LB1,
REG_CYCLES, REG_CYCLES2,
REG_USP = 0x70, REG_SEQSTAT, REG_SYSCFG,
- REG_RETI, REG_RETX, REG_RETN, REG_RETE, REG_EMUDAT,
+ REG_RETI, REG_RETX, REG_RETN, REG_RETE, REG_EMUDAT,
/* These don't have groups. */
REG_sftreset = T_NOGROUP, REG_omode, REG_excause, REG_emucause,
REG_A0 = 0xc0, REG_A1, REG_CC,
/* Pseudo registers, used only for distinction from symbols. */
REG_RL0, REG_RL1, REG_RL2, REG_RL3,
- REG_RL4, REG_RL5, REG_RL6, REG_RL7,
+ REG_RL4, REG_RL5, REG_RL6, REG_RL7,
REG_RH0, REG_RH1, REG_RH2, REG_RH3,
- REG_RH4, REG_RH5, REG_RH6, REG_RH7,
+ REG_RH4, REG_RH5, REG_RH6, REG_RH7,
REG_LASTREG
};
S_AV1S,
S_V = 24,
S_VS = 25
-};
+};
enum reg_class
/* Expression value macros. */
typedef enum
-{
+{
ones_compl,
twos_compl,
mult,
struct expressionS;
#define SYMBOL_T symbolS*
-
+
struct expression_cell
{
int value;
int pcrel;
int reloc;
};
-
+
#define INSTR_T struct bfin_insn*
-#define EXPR_T struct expression_cell*
+#define EXPR_T struct expression_cell*
typedef struct expr_node_struct Expr_Node;
-
+
extern INSTR_T gencode (unsigned long x);
-extern INSTR_T conscode (INSTR_T head, INSTR_T tail);
+extern INSTR_T conscode (INSTR_T head, INSTR_T tail);
extern INSTR_T conctcode (INSTR_T head, INSTR_T tail);
extern INSTR_T note_reloc
(INSTR_T code, Expr_Node *, int reloc,int pcrel);
(INSTR_T code, const char * sym, int reloc, int pcrel);
extern INSTR_T note_reloc2
(INSTR_T code, const char *symbol, int reloc, int value, int pcrel);
-
+
/* Types of expressions. */
-typedef enum
+typedef enum
{
Expr_Node_Binop, /* Binary operator. */
Expr_Node_Unop, /* Unary operator. */
} Expr_Node_Type;
/* Types of operators. */
-typedef enum
+typedef enum
{
Expr_Op_Type_Add,
Expr_Op_Type_Sub,
/* Operations on the expression node. */
-Expr_Node *Expr_Node_Create (Expr_Node_Type type,
- Expr_Node_Value value,
- Expr_Node *Left_Child,
+Expr_Node *Expr_Node_Create (Expr_Node_Type type,
+ Expr_Node_Value value,
+ Expr_Node *Left_Child,
Expr_Node *Right_Child);
/* Generate the reloc structure as a series of instructions. */
INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
-
+
#define MKREF(x) mkexpr (0,x)
#define ALLOCATE(x) malloc (x)
-
+
#define NULL_CODE ((INSTR_T) 0)
#ifndef EXPR_VALUE
{
va_list ap;
static char buffer[2000];
-
+
va_start (ap, format);
vsprintf (buffer, format, ap);
va_end (ap);
return yyerror ("Bad opt mode");
/* If a0macfunc comes before a1macfunc, swap them. */
-
+
if (aa->n == 0)
{
/* (M) is not allowed here. */
/* Make sure first macfunc has got both P flags ORed. */
aa->P |= ab->P;
- return 0;
+ return 0;
}
%token SHIFT LSHIFT ASHIFT BXORSHIFT
%token _GREATER_GREATER_GREATER_THAN_ASSIGN
%token ROT
-%token LESS_LESS GREATER_GREATER
+%token LESS_LESS GREATER_GREATER
%token _GREATER_GREATER_GREATER
%token _LESS_LESS_ASSIGN _GREATER_GREATER_ASSIGN
%token DIVS DIVQ
%type <reg> a_plusassign
%type <reg> a_minusassign
%type <macfunc> multiply_halfregs
-%type <macfunc> assign_macfunc
+%type <macfunc> assign_macfunc
%type <macfunc> a_macfunc
%type <expr> expr_1
%type <instr> asm_1
%type <reg> REG_A_DOUBLE_ZERO
%type <reg> REG_A_DOUBLE_ONE
%type <reg> REG_A
-%type <reg> STATUS_REG
+%type <reg> STATUS_REG
%type <expr> expr
%type <r0> xpmod
%type <r0> xpmod1
-%type <modcodes> smod
+%type <modcodes> smod
%type <modcodes> b3_op
%type <modcodes> rnd_op
%type <modcodes> post_op
%right TILDA BANG
%start statement
%%
-statement:
+statement:
| asm
{
insn = $1;
/* DSPMAC. */
-asm_1:
+asm_1:
MNOP
{
$$ = DSP32MAC (3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
if ($1.n == 0)
{
- if ($2.MM)
+ if ($2.MM)
return yyerror ("(m) not allowed with a0 unit");
op1 = 3;
op0 = $1.op;
{
Register *dst;
- if (check_macfuncs (&$1, &$2, &$4, &$5) < 0)
+ if (check_macfuncs (&$1, &$2, &$4, &$5) < 0)
return -1;
notethat ("assign_macfunc (.), assign_macfunc (.)\n");
notethat ("dsp32alu: dregs = ( A0 += A1 )\n");
$$ = DSP32ALU (11, 0, 0, &$1, 0, 0, 0, 0, 0);
}
- else
+ else
return yyerror ("Register mismatch");
- }
+ }
| HALF_REG ASSIGN LPAREN a_plusassign REG_A RPAREN
{
if (!IS_A1 ($4) && IS_A1 ($5))
}
| LPAREN REG COMMA REG RPAREN ASSIGN BYTEOP16M LPAREN REG COLON expr COMMA
- REG COLON expr RPAREN aligndir
+ REG COLON expr RPAREN aligndir
{
if (!IS_DREG ($2) || !IS_DREG ($4))
return yyerror ("Dregs expected");
}
- | REG ASSIGN REG_A PLUS REG_A COMMA REG ASSIGN REG_A MINUS REG_A amod1
+ | REG ASSIGN REG_A PLUS REG_A COMMA REG ASSIGN REG_A MINUS REG_A amod1
{
if (IS_DREG ($1) && IS_DREG ($7) && !REG_SAME ($3, $5)
&& IS_A1 ($9) && !IS_A1 ($11))
{
notethat ("dsp32alu: dregs = A1 + A0 , dregs = A1 - A0 (amod1)\n");
$$ = DSP32ALU (17, 0, &$1, &$7, 0, 0, $12.s0, $12.x0, 0);
-
+
}
else if (IS_DREG ($1) && IS_DREG ($7) && !REG_SAME ($3, $5)
&& !IS_A1 ($9) && IS_A1 ($11))
| REG ASSIGN REG plus_minus REG COMMA REG ASSIGN REG plus_minus REG amod1
{
- if ($4.r0 == $10.r0)
+ if ($4.r0 == $10.r0)
return yyerror ("Operators must differ");
if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5)
/* Bar Operations. */
- | REG ASSIGN REG op_bar_op REG COMMA REG ASSIGN REG op_bar_op REG amod2
+ | REG ASSIGN REG op_bar_op REG COMMA REG ASSIGN REG op_bar_op REG amod2
{
if (!REG_SAME ($3, $9) || !REG_SAME ($5, $11))
return yyerror ("Differing source registers");
- if (!IS_DREG ($1) || !IS_DREG ($3) || !IS_DREG ($5) || !IS_DREG ($7))
+ if (!IS_DREG ($1) || !IS_DREG ($3) || !IS_DREG ($5) || !IS_DREG ($7))
return yyerror ("Dregs expected");
-
+
if ($4.r0 == 1 && $10.r0 == 2)
{
notethat ("dsp32alu: dregs = dregs .|. dregs , dregs = dregs .|. dregs (amod2)\n");
}
| HALF_REG ASSIGN HALF_REG ASSIGN SIGN LPAREN HALF_REG RPAREN STAR
- HALF_REG PLUS SIGN LPAREN HALF_REG RPAREN STAR HALF_REG
+ HALF_REG PLUS SIGN LPAREN HALF_REG RPAREN STAR HALF_REG
{
if (IS_HCOMPL ($1, $3) && IS_HCOMPL ($7, $14) && IS_HCOMPL ($10, $17))
{
else
return yyerror ("Dregs expected");
}
- | REG ASSIGN REG plus_minus REG amod1
+ | REG ASSIGN REG plus_minus REG amod1
{
if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5))
{
return yyerror ("Dregs expected");
}
- | a_assign REG_A
+ | a_assign REG_A
{
if (!REG_SAME ($1, $2))
{
notethat ("LDIMMhalf: regs = luimm16 (x)\n");
/* reg, H, S, Z. */
$$ = LDIMMHALF_R5 (&$1, 0, 1, 0, $3);
- }
+ }
}
else
{
return yyerror ("Register mismatch");
}
- | REG ASSIGN REG op_bar_op REG amod0
+ | REG ASSIGN REG op_bar_op REG amod0
{
if (IS_DREG ($1) && IS_DREG ($3) && IS_DREG ($5))
{
else
return yyerror ("Register mismatch");
}
-
+
/* COMP3 CCFLAG. */
| REG ASSIGN REG BAR REG
{
notethat ("CC2dreg: CC =! CC\n");
$$ = bfin_gen_cc2dreg (3, 0);
}
-
+
/* DSPMULT. */
| HALF_REG ASSIGN multiply_halfregs opt_mode
else
{
$$ = DSP32MULT (0, 0, $4.mod, 0, 0,
- 0, 0, IS_H ($3.s0), IS_H ($3.s1),
+ 0, 0, IS_H ($3.s0), IS_H ($3.s1),
&$1, 0, &$3.s0, &$3.s1, 1);
}
}
- | REG ASSIGN multiply_halfregs opt_mode
+ | REG ASSIGN multiply_halfregs opt_mode
{
/* Odd registers can use (M). */
if (!IS_DREG ($1))
{
notethat ("dsp32mult: dregs = multiply_halfregs opt_mode\n");
$$ = DSP32MULT (0, 0, $4.mod, 0, 1,
- 0, 0, IS_H ($3.s0), IS_H ($3.s1),
+ 0, 0, IS_H ($3.s0), IS_H ($3.s1),
&$1, 0, &$3.s0, &$3.s1, 1);
}
}
| HALF_REG ASSIGN multiply_halfregs opt_mode COMMA
HALF_REG ASSIGN multiply_halfregs opt_mode
{
- if (!IS_DREG ($1) || !IS_DREG ($6))
+ if (!IS_DREG ($1) || !IS_DREG ($6))
return yyerror ("Dregs expected");
if (!IS_HCOMPL($1, $6))
| REG ASSIGN multiply_halfregs opt_mode COMMA REG ASSIGN multiply_halfregs opt_mode
{
- if (!IS_DREG ($1) || !IS_DREG ($6))
+ if (!IS_DREG ($1) || !IS_DREG ($6))
return yyerror ("Dregs expected");
if ((IS_EVEN ($1) && $6.regno - $1.regno != 1)
else
return yyerror ("Bad shift value or register");
}
- | HALF_REG ASSIGN HALF_REG LESS_LESS expr smod
+ | HALF_REG ASSIGN HALF_REG LESS_LESS expr smod
{
if (IS_UIMM ($5, 4))
{
}
else
{
-
+
op = 2;
notethat ("dsp32shift: dregs = ASHIFT dregs BY dregs_lo (.)\n");
}
return yyerror ("Register mismatch");
}
- | REG ASSIGN EXTRACT LPAREN REG COMMA HALF_REG RPAREN xpmod
+ | REG ASSIGN EXTRACT LPAREN REG COMMA HALF_REG RPAREN xpmod
{
if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG_L ($7))
{
return yyerror ("Register mismatch");
}
- | HALF_REG ASSIGN CCREG ASSIGN BXORSHIFT LPAREN REG_A COMMA REG RPAREN
+ | HALF_REG ASSIGN CCREG ASSIGN BXORSHIFT LPAREN REG_A COMMA REG RPAREN
{
if (IS_DREG ($1)
&& $7.regno == REG_A0
return yyerror ("Register mismatch");
}
- | a_assign ROT REG_A BY expr
+ | a_assign ROT REG_A BY expr
{
if (IS_IMM ($5, 6))
{
return yyerror ("Register mismatch");
}
- | REG ASSIGN ROT REG BY expr
+ | REG ASSIGN ROT REG BY expr
{
if (IS_DREG ($1) && IS_DREG ($4) && IS_IMM ($6, 6))
{
else
return yyerror ("Register mismatch");
}
-
+
/* The ASR bit is just inverted here. */
- | HALF_REG ASSIGN VIT_MAX LPAREN REG RPAREN asr_asl
+ | HALF_REG ASSIGN VIT_MAX LPAREN REG RPAREN asr_asl
{
if (IS_DREG_L ($1) && IS_DREG ($5))
{
return yyerror ("Register mismatch");
}
- | REG ASSIGN VIT_MAX LPAREN REG COMMA REG RPAREN asr_asl
+ | REG ASSIGN VIT_MAX LPAREN REG COMMA REG RPAREN asr_asl
{
if (IS_DREG ($1) && IS_DREG ($5) && IS_DREG ($7))
{
if ($4.r0)
tmp = unary (Expr_Op_Type_NEG, tmp);
-
+
if (in_range_p (tmp, -32768, 32767, 0))
{
notethat ("LDST: B [ pregs + imm16 ] = dregs\n");
return yyerror ("Dreg expected for source operand");
if (!IS_PREG ($3))
return yyerror ("Preg expected in address");
-
+
if ($4.r0)
tmp = unary (Expr_Op_Type_NEG, tmp);
}
else
return yyerror ("Displacement out of range");
- }
+ }
| HALF_REG ASSIGN W LBRACK REG post_op RBRACK
{
else
return yyerror ("Preg ++ Preg or Ireg ++ Mreg expected in address");
}
-
+
| W LBRACK REG _PLUS_PLUS REG RBRACK ASSIGN HALF_REG
{
if (!IS_DREG ($8))
$8.r0 ? 'X' : 'Z');
$$ = LDST (&$5, &$1, $6.x0, 2, $8.r0, 0);
}
-
+
| REG ASSIGN LBRACK REG _PLUS_PLUS REG RBRACK
{
if (!IS_DREG ($1))
{
notethat ("LDSTidxI: dpregs = [ pregs + imm18m4 ]\n");
$$ = LDSTIDXI (&$4, &$1, 0, 0, ispreg ? 1 : 0, tmp);
-
+
}
else
return yyerror ("Displacement out of range");
else
return yyerror ("Bad constant for LINK");
}
-
+
| UNLINK
{
notethat ("linkage: UNLINK\n");
}
else
return yyerror ("Bad register or values for LSETUP");
-
+
}
| LSETUP LPAREN expr COMMA expr RPAREN REG ASSIGN REG
{
| LSETUP LPAREN expr COMMA expr RPAREN REG ASSIGN REG GREATER_GREATER expr
{
if (IS_PCREL4 ($3) && IS_LPPCREL10 ($5)
- && IS_PREG ($9) && IS_CREG ($7)
+ && IS_PREG ($9) && IS_CREG ($7)
&& EXPR_VALUE ($11) == 1)
{
notethat ("LoopSetup: LSETUP (pcrel4 , lppcrel10 ) counters = pregs >> 1\n");
notethat ("pseudoDEBUG: DBGCMPLX (dregs )\n");
$$ = bfin_gen_pseudodbg (3, 6, $3.regno & CODE_MASK);
}
-
+
| DBGHALT
{
notethat ("psedoDEBUG: DBGHALT\n");
$$.x0 = 1;
}
| SCO
- {
+ {
$$.s0 = 1;
$$.x0 = 1;
}
$$.r0 = 0;
}
;
-
+
op_bar_op:
_PLUS_BAR_PLUS
{
post_op:
{
$$.x0 = 2;
- }
- | _PLUS_PLUS
+ }
+ | _PLUS_PLUS
{
$$.x0 = 0;
}
}
| expr_1 LESS_LESS expr_1
{
- $$ = binary (Expr_Op_Type_Lshift, $1, $3);
+ $$ = binary (Expr_Op_Type_Lshift, $1, $3);
}
| expr_1 GREATER_GREATER expr_1
{
{
$$ = binary (Expr_Op_Type_BOR, $1, $3);
}
- | eterm
+ | eterm
{
$$ = $1;
}
int umax = (1 << sz) - 1;
int min = -1 << (sz - 1);
int max = (1 << (sz - 1)) - 1;
-
+
int v = (EXPR_VALUE (exp)) & 0xffffffff;
if ((v % mul) != 0)
{
- error ("%s:%d: Value Error -- Must align to %d\n", __FILE__, __LINE__, mul);
+ error ("%s:%d: Value Error -- Must align to %d\n", __FILE__, __LINE__, mul);
return 0;
}
#endif
return 0;
}
- if (v <= umax && v >= 0)
+ if (v <= umax && v >= 0)
return 1;
#ifdef DEBUG
fprintf(stderr, "unsigned value %lx out of range\n", v * mul);
{
switch (op)
{
- case Expr_Op_Type_Add:
+ case Expr_Op_Type_Add:
x->value.i_value += y->value.i_value;
break;
- case Expr_Op_Type_Sub:
+ case Expr_Op_Type_Sub:
x->value.i_value -= y->value.i_value;
break;
- case Expr_Op_Type_Mult:
+ case Expr_Op_Type_Mult:
x->value.i_value *= y->value.i_value;
break;
- case Expr_Op_Type_Div:
+ case Expr_Op_Type_Div:
if (y->value.i_value == 0)
error ("Illegal Expression: Division by zero.");
else
x->value.i_value /= y->value.i_value;
break;
- case Expr_Op_Type_Mod:
+ case Expr_Op_Type_Mod:
x->value.i_value %= y->value.i_value;
break;
- case Expr_Op_Type_Lshift:
+ case Expr_Op_Type_Lshift:
x->value.i_value <<= y->value.i_value;
break;
- case Expr_Op_Type_Rshift:
+ case Expr_Op_Type_Rshift:
x->value.i_value >>= y->value.i_value;
break;
- case Expr_Op_Type_BAND:
+ case Expr_Op_Type_BAND:
x->value.i_value &= y->value.i_value;
break;
- case Expr_Op_Type_BOR:
+ case Expr_Op_Type_BOR:
x->value.i_value |= y->value.i_value;
break;
- case Expr_Op_Type_BXOR:
+ case Expr_Op_Type_BXOR:
x->value.i_value ^= y->value.i_value;
break;
- case Expr_Op_Type_LAND:
+ case Expr_Op_Type_LAND:
x->value.i_value = x->value.i_value && y->value.i_value;
break;
- case Expr_Op_Type_LOR:
+ case Expr_Op_Type_LOR:
x->value.i_value = x->value.i_value || y->value.i_value;
break;
}
static Expr_Node *
-unary (Expr_Op_Type op, Expr_Node *x)
+unary (Expr_Op_Type op, Expr_Node *x)
{
if (x->type == Expr_Node_Constant)
{
switch (op)
{
- case Expr_Op_Type_NEG:
+ case Expr_Op_Type_NEG:
x->value.i_value = -x->value.i_value;
break;
case Expr_Op_Type_COMP: