X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gas%2Fconfig%2Fbfin-parse.y;h=be532808a86aa05c27aafdd7985a311230a06ea5;hb=e0471c16c5ac8eddf49daf781248822f4a1ebc58;hp=b3416aa1130a7a7e2aedb71256843070cc1a664a;hpb=7333257119adc9883f90bf5ae1652001f4abf63d;p=external%2Fbinutils.git diff --git a/gas/config/bfin-parse.y b/gas/config/bfin-parse.y index b3416aa..be53280 100644 --- a/gas/config/bfin-parse.y +++ b/gas/config/bfin-parse.y @@ -1,12 +1,11 @@ /* bfin-parse.y ADI Blackfin parser - Copyright 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 2005-2016 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. GAS is distributed in the hope that it will be useful, @@ -21,9 +20,8 @@ %{ #include "as.h" -#include -#include "bfin-aux.h" // opcode generating auxiliaries +#include "bfin-aux.h" /* Opcode generating auxiliaries. */ #include "libbfd.h" #include "elf/common.h" #include "elf/bfin.h" @@ -152,7 +150,7 @@ (value_match (expr, 24, 0, 2, 1)) -static int value_match (Expr_Node *expr, int sz, int sign, int mul, int issigned); +static int value_match (Expr_Node *, int, int, int, int); extern FILE *errorf; extern INSTR_T insn; @@ -160,26 +158,29 @@ extern INSTR_T insn; static Expr_Node *binary (Expr_Op_Type, Expr_Node *, Expr_Node *); static Expr_Node *unary (Expr_Op_Type, Expr_Node *); -static void notethat (char *format, ...); +static void notethat (const char *, ...); char *current_inputline; extern char *yytext; -int yyerror (char *msg); +int yyerror (const char *); -void error (char *format, ...) +/* Used to set SRCx fields to all 1s as described in the PRM. */ +static Register reg7 = {REG_R7, 0}; + +void error (const char *format, ...) { va_list ap; - char buffer[2000]; - + static char buffer[2000]; + va_start (ap, format); vsprintf (buffer, format, ap); va_end (ap); - as_bad (buffer); + as_bad ("%s", buffer); } int -yyerror (char *msg) +yyerror (const char *msg) { if (msg[0] == '\0') error ("%s", msg); @@ -193,10 +194,10 @@ yyerror (char *msg) } static int -in_range_p (Expr_Node *expr, int from, int to, unsigned int mask) +in_range_p (Expr_Node *exp, int from, int to, unsigned int mask) { - int val = EXPR_VALUE (expr); - if (expr->type != Expr_Node_Constant) + int val = EXPR_VALUE (exp); + if (exp->type != Expr_Node_Constant) return 0; if (val < from || val > to) return 0; @@ -212,6 +213,7 @@ extern int yylex (void); #define uimm5(x) EXPR_VALUE (x) #define imm6(x) EXPR_VALUE (x) #define imm7(x) EXPR_VALUE (x) +#define uimm8(x) EXPR_VALUE (x) #define imm16(x) EXPR_VALUE (x) #define uimm16s4(x) ((EXPR_VALUE (x)) >> 2) #define uimm16(x) EXPR_VALUE (x) @@ -222,12 +224,6 @@ extern int yylex (void); /* Auxiliary functions. */ -static void -neg_value (Expr_Node *expr) -{ - expr->value.i_value = -expr->value.i_value; -} - static int valid_dreg_pair (Register *reg1, Expr_Node *reg2) { @@ -264,6 +260,29 @@ check_multiply_halfregs (Macfunc *aa, Macfunc *ab) } +/* Check mac option. */ + +static int +check_macfunc_option (Macfunc *a, Opt_mode *opt) +{ + /* Default option is always valid. */ + if (opt->mod == 0) + return 0; + + if ((a->w == 1 && a->P == 1 + && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_IU + && opt->mod != M_S2RND && opt->mod != M_ISS2) + || (a->w == 1 && a->P == 0 + && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_IU + && opt->mod != M_T && opt->mod != M_TFU && opt->mod != M_S2RND + && opt->mod != M_ISS2 && opt->mod != M_IH) + || (a->w == 0 && a->P == 0 + && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_W32)) + return -1; + + return 0; +} + /* Check (vector) mac funcs and ops. */ static int @@ -274,8 +293,13 @@ check_macfuncs (Macfunc *aa, Opt_mode *opa, Macfunc mtmp; Opt_mode otmp; + /* The option mode should be put at the end of the second instruction + of the vector except M, which should follow MAC1 instruction. */ + if (opa->mod != 0) + return yyerror ("Bad opt mode"); + /* If a0macfunc comes before a1macfunc, swap them. */ - + if (aa->n == 0) { /* (M) is not allowed here. */ @@ -291,16 +315,14 @@ check_macfuncs (Macfunc *aa, Opt_mode *opa, { if (opb->MM != 0) return yyerror ("(M) not allowed with A0MAC"); - if (opa->mod != 0) - return yyerror ("Bad opt mode"); if (ab->n != 0) return yyerror ("Vector AxMACs can't be same"); } /* If both ops are one of 0, 1, or 2, we have multiply_halfregs in both assignment_or_macfuncs. */ - if (aa->op < 3 && aa->op >=0 - && ab->op < 3 && ab->op >= 0) + if ((aa->op == 0 || aa->op == 1 || aa->op == 2) + && (ab->op == 0 || ab->op == 1 || ab->op == 2)) { if (check_multiply_halfregs (aa, ab) < 0) return -1; @@ -315,27 +337,29 @@ check_macfuncs (Macfunc *aa, Opt_mode *opa, aa->s1.regno |= (ab->s1.regno & CODE_MASK); } - if (aa->w == ab->w && aa->P != ab->P) + if (aa->w == ab->w && aa->P != ab->P) + return yyerror ("Destination Dreg sizes (full or half) must match"); + + if (aa->w && ab->w) { - return yyerror ("macfuncs must differ"); - if (aa->w && (aa->dst.regno - ab->dst.regno != 1)) - return yyerror ("Destination Dregs must differ by one"); + if (aa->P && (aa->dst.regno - ab->dst.regno) != 1) + return yyerror ("Destination Dregs (full) must differ by one"); + if (!aa->P && aa->dst.regno != ab->dst.regno) + return yyerror ("Destination Dregs (half) must match"); } - /* We assign to full regs, thus obey even/odd rules. */ - else if ((aa->w && aa->P && IS_EVEN (aa->dst)) - || (ab->w && ab->P && !IS_EVEN (ab->dst))) - return yyerror ("Even/Odd register assignment mismatch"); - /* We assign to half regs, thus obey hi/low rules. */ - else if ( (aa->w && !aa->P && !IS_H (aa->dst)) - || (ab->w && !aa->P && IS_H (ab->dst))) - return yyerror ("High/Low register assignment mismatch"); + + /* Make sure mod flags get ORed, too. */ + opb->mod |= opa->mod; + + /* Check option. */ + if (check_macfunc_option (aa, opb) < 0 + && check_macfunc_option (ab, opb) < 0) + return yyerror ("bad option"); /* Make sure first macfunc has got both P flags ORed. */ aa->P |= ab->P; - /* Make sure mod flags get ORed, too. */ - opb->mod |= opa->mod; - return 0; + return 0; } @@ -361,6 +385,62 @@ is_group2 (INSTR_T x) return 0; } +static int +is_store (INSTR_T x) +{ + if (!x) + return 0; + + if ((x->value & 0xf000) == 0x8000) + { + int aop = ((x->value >> 9) & 0x3); + int w = ((x->value >> 11) & 0x1); + if (!w || aop == 3) + return 0; + return 1; + } + + if (((x->value & 0xFF60) == 0x9E60) || /* dagMODim_0 */ + ((x->value & 0xFFF0) == 0x9F60)) /* dagMODik_0 */ + return 0; + + /* decode_dspLDST_0 */ + if ((x->value & 0xFC00) == 0x9C00) + { + int w = ((x->value >> 9) & 0x1); + if (w) + return 1; + } + + return 0; +} + +static INSTR_T +gen_multi_instr_1 (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2) +{ + int mask1 = dsp32 ? insn_regmask (dsp32->value, dsp32->next->value) : 0; + int mask2 = dsp16_grp1 ? insn_regmask (dsp16_grp1->value, 0) : 0; + int mask3 = dsp16_grp2 ? insn_regmask (dsp16_grp2->value, 0) : 0; + + if ((mask1 & mask2) || (mask1 & mask3) || (mask2 & mask3)) + yyerror ("resource conflict in multi-issue instruction"); + + /* Anomaly 05000074 */ + if (ENABLE_AC_05000074 + && dsp32 != NULL && dsp16_grp1 != NULL + && (dsp32->value & 0xf780) == 0xc680 + && ((dsp16_grp1->value & 0xfe40) == 0x9240 + || (dsp16_grp1->value & 0xfe08) == 0xba08 + || (dsp16_grp1->value & 0xfc00) == 0xbc00)) + yyerror ("anomaly 05000074 - Multi-Issue Instruction with \ +dsp32shiftimm in slot1 and P-reg Store in slot2 Not Supported"); + + if (is_store (dsp16_grp1) && is_store (dsp16_grp2)) + yyerror ("Only one instruction in multi-issue instruction can be a store"); + + return bfin_gen_multi_instr (dsp32, dsp16_grp1, dsp16_grp2); +} + %} %union { @@ -380,7 +460,7 @@ is_group2 (INSTR_T x) /* Vector Specific. */ %token BYTEOP16P BYTEOP16M -%token BYTEOP1P BYTEOP2P BYTEOP2M BYTEOP3P +%token BYTEOP1P BYTEOP2P BYTEOP3P %token BYTEUNPACK BYTEPACK %token PACK %token SAA @@ -437,7 +517,7 @@ is_group2 (INSTR_T x) %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 @@ -504,8 +584,8 @@ is_group2 (INSTR_T x) %type a_plusassign %type a_minusassign %type multiply_halfregs -%type assign_macfunc -%type a_macfunc +%type assign_macfunc +%type a_macfunc %type expr_1 %type asm_1 %type vmod @@ -525,11 +605,11 @@ is_group2 (INSTR_T x) %type REG_A_DOUBLE_ZERO %type REG_A_DOUBLE_ONE %type REG_A -%type STATUS_REG +%type STATUS_REG %type expr %type xpmod %type xpmod1 -%type smod +%type smod %type b3_op %type rnd_op %type post_op @@ -564,7 +644,7 @@ is_group2 (INSTR_T x) %right TILDA BANG %start statement %% -statement: +statement: | asm { insn = $1; @@ -584,27 +664,27 @@ asm: asm_1 SEMICOLON if (($1->value & 0xf800) == 0xc000) { if (is_group1 ($3) && is_group2 ($5)) - $$ = bfin_gen_multi_instr ($1, $3, $5); + $$ = gen_multi_instr_1 ($1, $3, $5); else if (is_group2 ($3) && is_group1 ($5)) - $$ = bfin_gen_multi_instr ($1, $5, $3); + $$ = gen_multi_instr_1 ($1, $5, $3); else return yyerror ("Wrong 16 bit instructions groups, slot 2 and slot 3 must be 16-bit instrution group"); } else if (($3->value & 0xf800) == 0xc000) { if (is_group1 ($1) && is_group2 ($5)) - $$ = bfin_gen_multi_instr ($3, $1, $5); + $$ = gen_multi_instr_1 ($3, $1, $5); else if (is_group2 ($1) && is_group1 ($5)) - $$ = bfin_gen_multi_instr ($3, $5, $1); + $$ = gen_multi_instr_1 ($3, $5, $1); else return yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 3 must be 16-bit instrution group"); } else if (($5->value & 0xf800) == 0xc000) { if (is_group1 ($1) && is_group2 ($3)) - $$ = bfin_gen_multi_instr ($5, $1, $3); + $$ = gen_multi_instr_1 ($5, $1, $3); else if (is_group2 ($1) && is_group1 ($3)) - $$ = bfin_gen_multi_instr ($5, $3, $1); + $$ = gen_multi_instr_1 ($5, $3, $1); else return yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 2 must be 16-bit instrution group"); } @@ -617,25 +697,25 @@ asm: asm_1 SEMICOLON if (($1->value & 0xf800) == 0xc000) { if (is_group1 ($3)) - $$ = bfin_gen_multi_instr ($1, $3, 0); + $$ = gen_multi_instr_1 ($1, $3, 0); else if (is_group2 ($3)) - $$ = bfin_gen_multi_instr ($1, 0, $3); + $$ = gen_multi_instr_1 ($1, 0, $3); else return yyerror ("Wrong 16 bit instructions groups, slot 2 must be the 16-bit instruction group"); } else if (($3->value & 0xf800) == 0xc000) { if (is_group1 ($1)) - $$ = bfin_gen_multi_instr ($3, $1, 0); + $$ = gen_multi_instr_1 ($3, $1, 0); else if (is_group2 ($1)) - $$ = bfin_gen_multi_instr ($3, 0, $1); + $$ = gen_multi_instr_1 ($3, 0, $1); else return yyerror ("Wrong 16 bit instructions groups, slot 1 must be the 16-bit instruction group"); } else if (is_group1 ($1) && is_group2 ($3)) - $$ = bfin_gen_multi_instr (0, $1, $3); + $$ = gen_multi_instr_1 (0, $1, $3); else if (is_group2 ($1) && is_group1 ($3)) - $$ = bfin_gen_multi_instr (0, $3, $1); + $$ = gen_multi_instr_1 (0, $3, $1); else return yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 2 must be the 16-bit instruction group"); } @@ -649,7 +729,7 @@ asm: asm_1 SEMICOLON /* DSPMAC. */ -asm_1: +asm_1: MNOP { $$ = DSP32MAC (3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); @@ -660,9 +740,12 @@ asm_1: int w0 = 0, w1 = 0; int h00, h10, h01, h11; + if (check_macfunc_option (&$1, &$2) < 0) + return yyerror ("bad option"); + if ($1.n == 0) { - if ($2.MM) + if ($2.MM) return yyerror ("(m) not allowed with a0 unit"); op1 = 3; op0 = $1.op; @@ -693,7 +776,7 @@ asm_1: { 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"); @@ -719,17 +802,17 @@ asm_1: if (IS_DREG ($1) && !IS_A1 ($4) && IS_A1 ($5)) { notethat ("dsp32alu: dregs = ( A0 += A1 )\n"); - $$ = DSP32ALU (11, 0, 0, &$1, 0, 0, 0, 0, 0); + $$ = DSP32ALU (11, 0, 0, &$1, ®7, ®7, 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)) { notethat ("dsp32alu: dregs_half = ( A0 += A1 )\n"); - $$ = DSP32ALU (11, IS_H ($1), 0, &$1, 0, 0, 0, 0, 1); + $$ = DSP32ALU (11, IS_H ($1), 0, &$1, ®7, ®7, 0, 0, 1); } else return yyerror ("Register mismatch"); @@ -749,22 +832,26 @@ asm_1: { if (!IS_DREG ($2) || !IS_DREG ($4)) return yyerror ("Dregs expected"); + else if (REG_SAME ($2, $4)) + return yyerror ("Illegal dest register combination"); else if (!valid_dreg_pair (&$9, $11)) return yyerror ("Bad dreg pair"); else if (!valid_dreg_pair (&$13, $15)) return yyerror ("Bad dreg pair"); else { - notethat ("dsp32alu: (dregs , dregs ) = BYTEOP16P (dregs_pair , dregs_pair ) (half)\n"); + notethat ("dsp32alu: (dregs , dregs ) = BYTEOP16P (dregs_pair , dregs_pair ) (aligndir)\n"); $$ = DSP32ALU (21, 0, &$2, &$4, &$9, &$13, $17.r0, 0, 0); } } | 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)) + if (!IS_DREG ($2) || !IS_DREG ($4)) return yyerror ("Dregs expected"); + else if (REG_SAME ($2, $4)) + return yyerror ("Illegal dest register combination"); else if (!valid_dreg_pair (&$9, $11)) return yyerror ("Bad dreg pair"); else if (!valid_dreg_pair (&$13, $15)) @@ -780,6 +867,8 @@ asm_1: { if (!IS_DREG ($2) || !IS_DREG ($4)) return yyerror ("Dregs expected"); + else if (REG_SAME ($2, $4)) + return yyerror ("Illegal dest register combination"); else if (!valid_dreg_pair (&$8, $10)) return yyerror ("Bad dreg pair"); else @@ -790,6 +879,9 @@ asm_1: } | LPAREN REG COMMA REG RPAREN ASSIGN SEARCH REG LPAREN searchmod RPAREN { + if (REG_SAME ($2, $4)) + return yyerror ("Illegal dest register combination"); + if (IS_DREG ($2) && IS_DREG ($4) && IS_DREG ($8)) { notethat ("dsp32alu: (dregs , dregs ) = SEARCH dregs (searchmod)\n"); @@ -801,30 +893,36 @@ asm_1: | REG ASSIGN A_ONE_DOT_L PLUS A_ONE_DOT_H COMMA REG ASSIGN A_ZERO_DOT_L PLUS A_ZERO_DOT_H { + if (REG_SAME ($1, $7)) + return yyerror ("Illegal dest register combination"); + if (IS_DREG ($1) && IS_DREG ($7)) { notethat ("dsp32alu: dregs = A1.l + A1.h, dregs = A0.l + A0.h \n"); - $$ = DSP32ALU (12, 0, &$1, &$7, 0, 0, 0, 0, 1); + $$ = DSP32ALU (12, 0, &$1, &$7, ®7, ®7, 0, 0, 1); } else return yyerror ("Register mismatch"); } - | 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 (REG_SAME ($1, $7)) + return yyerror ("Resource conflict in dest reg"); + 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); - + $$ = DSP32ALU (17, 0, &$1, &$7, ®7, ®7, $12.s0, $12.x0, 0); + } else if (IS_DREG ($1) && IS_DREG ($7) && !REG_SAME ($3, $5) && !IS_A1 ($9) && IS_A1 ($11)) { notethat ("dsp32alu: dregs = A0 + A1 , dregs = A0 - A1 (amod1)\n"); - $$ = DSP32ALU (17, 0, &$1, &$7, 0, 0, $12.s0, $12.x0, 1); + $$ = DSP32ALU (17, 0, &$1, &$7, ®7, ®7, $12.s0, $12.x0, 1); } else return yyerror ("Register mismatch"); @@ -832,7 +930,7 @@ asm_1: | 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) @@ -848,15 +946,17 @@ asm_1: /* 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 (REG_SAME ($1, $7)) + return yyerror ("Resource conflict in dest reg"); + if ($4.r0 == 1 && $10.r0 == 2) { notethat ("dsp32alu: dregs = dregs .|. dregs , dregs = dregs .|. dregs (amod2)\n"); @@ -896,7 +996,7 @@ asm_1: | a_assign ABS REG_A { notethat ("dsp32alu: Ax = ABS Ax\n"); - $$ = DSP32ALU (16, IS_A1 ($1), 0, 0, 0, 0, 0, 0, IS_A1 ($3)); + $$ = DSP32ALU (16, IS_A1 ($1), 0, 0, ®7, ®7, 0, 0, IS_A1 ($3)); } | A_ZERO_DOT_L ASSIGN HALF_REG { @@ -975,22 +1075,6 @@ asm_1: } } - | REG ASSIGN BYTEOP2M LPAREN REG COLON expr COMMA REG COLON expr RPAREN - rnd_op - { - if (!IS_DREG ($1)) - return yyerror ("Dregs expected"); - else if (!valid_dreg_pair (&$5, $7)) - return yyerror ("Bad dreg pair"); - else if (!valid_dreg_pair (&$9, $11)) - return yyerror ("Bad dreg pair"); - else - { - notethat ("dsp32alu: dregs = BYTEOP2P (dregs_pair , dregs_pair ) (rnd_op)\n"); - $$ = DSP32ALU (22, $13.r0, 0, &$1, &$5, &$9, $13.s0, 0, $13.x0); - } - } - | REG ASSIGN BYTEOP3P LPAREN REG COLON expr COMMA REG COLON expr RPAREN b3_op { @@ -1019,7 +1103,7 @@ asm_1: } | 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)) { @@ -1032,7 +1116,7 @@ asm_1: 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)) { @@ -1079,7 +1163,7 @@ asm_1: | a_assign MINUS REG_A { notethat ("dsp32alu: Ax = - Ax\n"); - $$ = DSP32ALU (14, IS_A1 ($1), 0, 0, 0, 0, 0, 0, IS_A1 ($3)); + $$ = DSP32ALU (14, IS_A1 ($1), 0, 0, ®7, ®7, 0, 0, IS_A1 ($3)); } | HALF_REG ASSIGN HALF_REG plus_minus HALF_REG amod1 { @@ -1092,7 +1176,7 @@ asm_1: if (EXPR_VALUE ($3) == 0 && !REG_SAME ($1, $2)) { notethat ("dsp32alu: A1 = A0 = 0\n"); - $$ = DSP32ALU (8, 0, 0, 0, 0, 0, 0, 0, 2); + $$ = DSP32ALU (8, 0, 0, 0, ®7, ®7, 0, 0, 2); } else return yyerror ("Bad value, 0 expected"); @@ -1104,7 +1188,7 @@ asm_1: if (REG_SAME ($1, $2)) { notethat ("dsp32alu: Ax = Ax (S)\n"); - $$ = DSP32ALU (8, 0, 0, 0, 0, 0, 1, 0, IS_A1 ($1)); + $$ = DSP32ALU (8, 0, 0, 0, ®7, ®7, 1, 0, IS_A1 ($1)); } else return yyerror ("Registers must be equal"); @@ -1143,12 +1227,12 @@ asm_1: return yyerror ("Dregs expected"); } - | a_assign REG_A + | a_assign REG_A { if (!REG_SAME ($1, $2)) { notethat ("dsp32alu: An = Am\n"); - $$ = DSP32ALU (8, 0, 0, 0, 0, 0, IS_A1 ($1), 0, 3); + $$ = DSP32ALU (8, 0, 0, 0, ®7, ®7, IS_A1 ($1), 0, 3); } else return yyerror ("Accu reg arguments must differ"); @@ -1244,7 +1328,7 @@ asm_1: notethat ("LDIMMhalf: regs = luimm16 (x)\n"); /* reg, H, S, Z. */ $$ = LDIMMHALF_R5 (&$1, 0, 1, 0, $3); - } + } } else { @@ -1268,18 +1352,18 @@ asm_1: if (IS_DREG ($1) && $3.regno == REG_A0x) { notethat ("dsp32alu: dregs_lo = A0.x\n"); - $$ = DSP32ALU (10, 0, 0, &$1, 0, 0, 0, 0, 0); + $$ = DSP32ALU (10, 0, 0, &$1, ®7, ®7, 0, 0, 0); } else if (IS_DREG ($1) && $3.regno == REG_A1x) { notethat ("dsp32alu: dregs_lo = A1.x\n"); - $$ = DSP32ALU (10, 0, 0, &$1, 0, 0, 0, 0, 1); + $$ = DSP32ALU (10, 0, 0, &$1, ®7, ®7, 0, 0, 1); } 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)) { @@ -1306,7 +1390,7 @@ asm_1: if (REG_SAME ($1, $3) && REG_SAME ($5, $7) && !REG_SAME ($1, $5)) { notethat ("dsp32alu: A1 = ABS A1 , A0 = ABS A0\n"); - $$ = DSP32ALU (16, 0, 0, 0, 0, 0, 0, 0, 3); + $$ = DSP32ALU (16, 0, 0, 0, ®7, ®7, 0, 0, 3); } else return yyerror ("Register mismatch"); @@ -1317,7 +1401,7 @@ asm_1: if (REG_SAME ($1, $3) && REG_SAME ($5, $7) && !REG_SAME ($1, $5)) { notethat ("dsp32alu: A1 = - A1 , A0 = - A0\n"); - $$ = DSP32ALU (14, 0, 0, 0, 0, 0, 0, 0, 3); + $$ = DSP32ALU (14, 0, 0, 0, ®7, ®7, 0, 0, 3); } else return yyerror ("Register mismatch"); @@ -1328,7 +1412,7 @@ asm_1: if (!IS_A1 ($1) && IS_A1 ($2)) { notethat ("dsp32alu: A0 -= A1\n"); - $$ = DSP32ALU (11, 0, 0, 0, 0, 0, $3.r0, 0, 3); + $$ = DSP32ALU (11, 0, 0, 0, ®7, ®7, $3.r0, 0, 3); } else return yyerror ("Register mismatch"); @@ -1388,7 +1472,7 @@ asm_1: if (!IS_A1 ($1) && IS_A1 ($3)) { notethat ("dsp32alu: A0 += A1 (W32)\n"); - $$ = DSP32ALU (11, 0, 0, 0, 0, 0, $4.r0, 0, 2); + $$ = DSP32ALU (11, 0, 0, 0, ®7, ®7, $4.r0, 0, 2); } else return yyerror ("Register mismatch"); @@ -1432,6 +1516,8 @@ asm_1: notethat ("COMPI2opD: dregs += imm7\n"); $$ = COMPI2OPD (&$1, imm7 ($3), 1); } + else if ((IS_DREG ($1) || IS_PREG ($1)) && IS_CONST ($3)) + return yyerror ("Immediate value out of range"); else return yyerror ("Register mismatch"); } @@ -1465,7 +1551,7 @@ asm_1: if (REG_SAME ($1, $2) && REG_SAME ($7, $8) && !REG_SAME ($1, $7)) { notethat ("dsp32alu: A1 = A1 (S) , A0 = A0 (S)\n"); - $$ = DSP32ALU (8, 0, 0, 0, 0, 0, 1, 0, 2); + $$ = DSP32ALU (8, 0, 0, 0, ®7, ®7, 1, 0, 2); } else return yyerror ("Register mismatch"); @@ -1508,7 +1594,7 @@ asm_1: else return yyerror ("Register mismatch"); } - + /* COMP3 CCFLAG. */ | REG ASSIGN REG BAR REG { @@ -1552,36 +1638,40 @@ asm_1: } | CCREG ASSIGN REG_A _ASSIGN_ASSIGN REG_A { - if (!REG_SAME ($3, $5)) + if ($3.regno == REG_A0 && $5.regno == REG_A1) { notethat ("CCflag: CC = A0 == A1\n"); $$ = CCFLAG (0, 0, 5, 0, 0); } else - return yyerror ("CC register expected"); + return yyerror ("AREGs are in bad order or same"); } | CCREG ASSIGN REG_A LESS_THAN REG_A { - if (!REG_SAME ($3, $5)) + if ($3.regno == REG_A0 && $5.regno == REG_A1) { notethat ("CCflag: CC = A0 < A1\n"); $$ = CCFLAG (0, 0, 6, 0, 0); } else - return yyerror ("Register mismatch"); + return yyerror ("AREGs are in bad order or same"); } | CCREG ASSIGN REG LESS_THAN REG iu_or_nothing { - if (REG_CLASS($3) == REG_CLASS($5)) + if ((IS_DREG ($3) && IS_DREG ($5)) + || (IS_PREG ($3) && IS_PREG ($5))) { notethat ("CCflag: CC = dpregs < dpregs\n"); $$ = CCFLAG (&$3, $5.regno & CODE_MASK, $6.r0, 0, IS_PREG ($3) ? 1 : 0); } else - return yyerror ("Compare only of same register class"); + return yyerror ("Bad register in comparison"); } | CCREG ASSIGN REG LESS_THAN expr iu_or_nothing { + if (!IS_DREG ($3) && !IS_PREG ($3)) + return yyerror ("Bad register in comparison"); + if (($6.r0 == 1 && IS_IMM ($5, 3)) || ($6.r0 == 3 && IS_UIMM ($5, 3))) { @@ -1593,14 +1683,20 @@ asm_1: } | CCREG ASSIGN REG _ASSIGN_ASSIGN REG { - if (REG_CLASS($3) == REG_CLASS($5)) + if ((IS_DREG ($3) && IS_DREG ($5)) + || (IS_PREG ($3) && IS_PREG ($5))) { notethat ("CCflag: CC = dpregs == dpregs\n"); $$ = CCFLAG (&$3, $5.regno & CODE_MASK, 0, 0, IS_PREG ($3) ? 1 : 0); - } + } + else + return yyerror ("Bad register in comparison"); } | CCREG ASSIGN REG _ASSIGN_ASSIGN expr { + if (!IS_DREG ($3) && !IS_PREG ($3)) + return yyerror ("Bad register in comparison"); + if (IS_IMM ($5, 3)) { notethat ("CCflag: CC = dpregs == imm3\n"); @@ -1611,44 +1707,36 @@ asm_1: } | CCREG ASSIGN REG_A _LESS_THAN_ASSIGN REG_A { - if (!REG_SAME ($3, $5)) + if ($3.regno == REG_A0 && $5.regno == REG_A1) { notethat ("CCflag: CC = A0 <= A1\n"); $$ = CCFLAG (0, 0, 7, 0, 0); } else - return yyerror ("CC register expected"); + return yyerror ("AREGs are in bad order or same"); } | CCREG ASSIGN REG _LESS_THAN_ASSIGN REG iu_or_nothing { - if (REG_CLASS($3) == REG_CLASS($5)) + if ((IS_DREG ($3) && IS_DREG ($5)) + || (IS_PREG ($3) && IS_PREG ($5))) { - notethat ("CCflag: CC = pregs <= pregs (..)\n"); + notethat ("CCflag: CC = dpregs <= dpregs (..)\n"); $$ = CCFLAG (&$3, $5.regno & CODE_MASK, 1 + $6.r0, 0, IS_PREG ($3) ? 1 : 0); } else - return yyerror ("Compare only of same register class"); + return yyerror ("Bad register in comparison"); } | CCREG ASSIGN REG _LESS_THAN_ASSIGN expr iu_or_nothing { + if (!IS_DREG ($3) && !IS_PREG ($3)) + return yyerror ("Bad register in comparison"); + if (($6.r0 == 1 && IS_IMM ($5, 3)) || ($6.r0 == 3 && IS_UIMM ($5, 3))) { - if (IS_DREG ($3)) - { - notethat ("CCflag: CC = dregs <= (u)imm3\n"); - /* x y opc I G */ - $$ = CCFLAG (&$3, imm3 ($5), 1 + $6.r0, 1, 0); - } - else if (IS_PREG ($3)) - { - notethat ("CCflag: CC = pregs <= (u)imm3\n"); - /* x y opc I G */ - $$ = CCFLAG (&$3, imm3 ($5), 1 + $6.r0, 1, 1); - } - else - return yyerror ("Dreg or Preg expected"); + notethat ("CCflag: CC = dpregs <= (u)imm3\n"); + $$ = CCFLAG (&$3, imm3 ($5), 1 + $6.r0, 1, IS_PREG ($3) ? 1 : 0); } else return yyerror ("Bad constant value"); @@ -1673,13 +1761,24 @@ asm_1: | REG ASSIGN REG { - if (IS_ALLREG ($1) && IS_ALLREG ($3)) + if ((IS_GENREG ($1) && IS_GENREG ($3)) + || (IS_GENREG ($1) && IS_DAGREG ($3)) + || (IS_DAGREG ($1) && IS_GENREG ($3)) + || (IS_DAGREG ($1) && IS_DAGREG ($3)) + || (IS_GENREG ($1) && $3.regno == REG_USP) + || ($1.regno == REG_USP && IS_GENREG ($3)) + || ($1.regno == REG_USP && $3.regno == REG_USP) + || (IS_DREG ($1) && IS_SYSREG ($3)) + || (IS_PREG ($1) && IS_SYSREG ($3)) + || (IS_SYSREG ($1) && IS_GENREG ($3)) + || (IS_ALLREG ($1) && IS_EMUDAT ($3)) + || (IS_EMUDAT ($1) && IS_ALLREG ($3)) + || (IS_SYSREG ($1) && $3.regno == REG_USP)) { - notethat ("REGMV: allregs = allregs\n"); $$ = bfin_gen_regmv (&$3, &$1); } else - return yyerror ("Register mismatch"); + return yyerror ("Unsupported register move"); } | CCREG ASSIGN REG @@ -1690,7 +1789,7 @@ asm_1: $$ = bfin_gen_cc2dreg (1, &$3); } else - return yyerror ("Register mismatch"); + return yyerror ("Only 'CC = Dreg' supported"); } | REG ASSIGN CCREG @@ -1701,7 +1800,7 @@ asm_1: $$ = bfin_gen_cc2dreg (0, &$1); } else - return yyerror ("Register mismatch"); + return yyerror ("Only 'Dreg = CC' supported"); } | CCREG _ASSIGN_BANG CCREG @@ -1709,7 +1808,7 @@ asm_1: notethat ("CC2dreg: CC =! CC\n"); $$ = bfin_gen_cc2dreg (3, 0); } - + /* DSPMULT. */ | HALF_REG ASSIGN multiply_halfregs opt_mode @@ -1719,6 +1818,11 @@ asm_1: if (!IS_H ($1) && $4.MM) return yyerror ("(M) not allowed with MAC0"); + if ($4.mod != 0 && $4.mod != M_FU && $4.mod != M_IS + && $4.mod != M_IU && $4.mod != M_T && $4.mod != M_TFU + && $4.mod != M_S2RND && $4.mod != M_ISS2 && $4.mod != M_IH) + return yyerror ("bad option."); + if (IS_H ($1)) { $$ = DSP32MULT (0, $4.MM, $4.mod, 1, 0, @@ -1728,12 +1832,12 @@ asm_1: 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)) @@ -1742,6 +1846,10 @@ asm_1: if (IS_EVEN ($1) && $4.MM) return yyerror ("(M) not allowed with MAC0"); + if ($4.mod != 0 && $4.mod != M_FU && $4.mod != M_IS + && $4.mod != M_S2RND && $4.mod != M_ISS2) + return yyerror ("bad option"); + if (!IS_EVEN ($1)) { notethat ("dsp32mult: dregs = multiply_halfregs (opt_mode)\n"); @@ -1754,7 +1862,7 @@ asm_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); } } @@ -1762,7 +1870,7 @@ asm_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)) @@ -1790,7 +1898,7 @@ asm_1: | 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) @@ -1892,22 +2000,20 @@ asm_1: else return yyerror ("Bad shift value or register"); } - | HALF_REG ASSIGN HALF_REG LESS_LESS expr + | HALF_REG ASSIGN HALF_REG LESS_LESS expr smod { if (IS_UIMM ($5, 4)) { - notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4\n"); - $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, 2, HL2 ($1, $3)); - } - else - return yyerror ("Bad shift value"); - } - | HALF_REG ASSIGN HALF_REG LESS_LESS expr smod - { - if (IS_UIMM ($5, 4)) - { - notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4\n"); - $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, $6.s0, HL2 ($1, $3)); + if ($6.s0) + { + notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4 (S)\n"); + $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, $6.s0, HL2 ($1, $3)); + } + else + { + notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4\n"); + $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, 2, HL2 ($1, $3)); + } } else return yyerror ("Bad shift value"); @@ -1926,7 +2032,7 @@ asm_1: } else { - + op = 2; notethat ("dsp32shift: dregs = ASHIFT dregs BY dregs_lo (.)\n"); } @@ -1989,7 +2095,7 @@ asm_1: 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)) { @@ -2166,7 +2272,7 @@ asm_1: 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 @@ -2225,7 +2331,7 @@ asm_1: return yyerror ("Register mismatch"); } - | a_assign ROT REG_A BY expr + | a_assign ROT REG_A BY expr { if (IS_IMM ($5, 6)) { @@ -2236,7 +2342,7 @@ asm_1: 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)) { @@ -2278,9 +2384,9 @@ asm_1: 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)) { @@ -2291,7 +2397,7 @@ asm_1: 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)) { @@ -2304,6 +2410,9 @@ asm_1: | BITMUX LPAREN REG COMMA REG COMMA REG_A RPAREN asr_asl { + if (REG_SAME ($3, $5)) + return yyerror ("Illegal source register combination"); + if (IS_DREG ($3) && IS_DREG ($5) && !IS_A1 ($7)) { notethat ("dsp32shift: BITMUX (dregs , dregs , A0) (ASR)\n"); @@ -2597,6 +2706,9 @@ asm_1: { if (IS_PREG ($3)) { + if ($3.regno == REG_SP || $3.regno == REG_FP) + return yyerror ("Bad register for TESTSET"); + notethat ("ProgCtrl: TESTSET (pregs )\n"); $$ = PROGCTRL (11, $3.regno & CODE_MASK); } @@ -2883,76 +2995,105 @@ asm_1: | B LBRACK REG post_op RBRACK ASSIGN REG { - if (IS_PREG ($3) && IS_DREG ($7)) - { - notethat ("LDST: B [ pregs ] = dregs\n"); - $$ = LDST (&$3, &$7, $4.x0, 2, 0, 1); - } - else - return yyerror ("Register mismatch"); + if (!IS_DREG ($7)) + return yyerror ("Dreg expected for source operand"); + if (!IS_PREG ($3)) + return yyerror ("Preg expected in address"); + + notethat ("LDST: B [ pregs ] = dregs\n"); + $$ = LDST (&$3, &$7, $4.x0, 2, 0, 1); } /* LDSTidxI: B [ pregs + imm16 ] = dregs. */ | B LBRACK REG plus_minus expr RBRACK ASSIGN REG { - if (IS_PREG ($3) && IS_RANGE(16, $5, $4.r0, 1) && IS_DREG ($8)) + Expr_Node *tmp = $5; + + if (!IS_DREG ($8)) + return yyerror ("Dreg expected for source operand"); + if (!IS_PREG ($3)) + return yyerror ("Preg expected in address"); + + if (IS_RELOC ($5)) + return yyerror ("Plain symbol used as offset"); + + 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"); - if ($4.r0) - neg_value ($5); $$ = LDSTIDXI (&$3, &$8, 1, 2, 0, $5); } else - return yyerror ("Register mismatch or const size wrong"); + return yyerror ("Displacement out of range"); } /* LDSTii: W [ pregs + uimm4s2 ] = dregs. */ | W LBRACK REG plus_minus expr RBRACK ASSIGN REG { - if (IS_PREG ($3) && IS_URANGE (4, $5, $4.r0, 2) && IS_DREG ($8)) + Expr_Node *tmp = $5; + + if (!IS_DREG ($8)) + 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); + + if (IS_RELOC ($5)) + return yyerror ("Plain symbol used as offset"); + + if (in_range_p (tmp, 0, 30, 1)) { notethat ("LDSTii: W [ pregs +- uimm5m2 ] = dregs\n"); - $$ = LDSTII (&$3, &$8, $5, 1, 1); + $$ = LDSTII (&$3, &$8, tmp, 1, 1); } - else if (IS_PREG ($3) && IS_RANGE(16, $5, $4.r0, 2) && IS_DREG ($8)) + else if (in_range_p (tmp, -65536, 65535, 1)) { notethat ("LDSTidxI: W [ pregs + imm17m2 ] = dregs\n"); - if ($4.r0) - neg_value ($5); - $$ = LDSTIDXI (&$3, &$8, 1, 1, 0, $5); + $$ = LDSTIDXI (&$3, &$8, 1, 1, 0, tmp); } else - return yyerror ("Bad register(s) or wrong constant size"); + return yyerror ("Displacement out of range"); } /* LDST: W [ pregs ] = dregs. */ | W LBRACK REG post_op RBRACK ASSIGN REG { - if (IS_PREG ($3) && IS_DREG ($7)) - { - notethat ("LDST: W [ pregs ] = dregs\n"); - $$ = LDST (&$3, &$7, $4.x0, 1, 0, 1); - } - else - return yyerror ("Bad register(s) for STORE"); + if (!IS_DREG ($7)) + return yyerror ("Dreg expected for source operand"); + if (!IS_PREG ($3)) + return yyerror ("Preg expected in address"); + + notethat ("LDST: W [ pregs ] = dregs\n"); + $$ = LDST (&$3, &$7, $4.x0, 1, 0, 1); } | W LBRACK REG post_op RBRACK ASSIGN HALF_REG { + if (!IS_DREG ($7)) + return yyerror ("Dreg expected for source operand"); + if ($4.x0 == 2) + { + if (!IS_IREG ($3) && !IS_PREG ($3)) + return yyerror ("Ireg or Preg expected in address"); + } + else if (!IS_IREG ($3)) + return yyerror ("Ireg expected in address"); + if (IS_IREG ($3)) { notethat ("dspLDST: W [ iregs ] = dregs_half\n"); $$ = DSPLDST (&$3, 1 + IS_H ($7), &$7, $4.x0, 1); } - else if ($4.x0 == 2 && IS_PREG ($3) && IS_DREG ($7)) + else { - notethat ("LDSTpmod: W [ pregs ] = dregs_half\n"); + notethat ("LDSTpmod: W [ pregs ] = dregs_half\n"); $$ = LDSTPMOD (&$3, &$7, &$3, 1 + IS_H ($7), 1); - } - else - return yyerror ("Bad register(s) for STORE"); } /* LDSTiiFP: [ FP - const ] = dpregs. */ @@ -2962,14 +3103,17 @@ asm_1: int ispreg = IS_PREG ($7); if (!IS_PREG ($2)) - return yyerror ("Preg expected for indirect"); + return yyerror ("Preg expected in address"); if (!IS_DREG ($7) && !ispreg) - return yyerror ("Bad source register for STORE"); + return yyerror ("Preg expected for source operand"); if ($3.r0) tmp = unary (Expr_Op_Type_NEG, tmp); + if (IS_RELOC ($4)) + return yyerror ("Plain symbol used as offset"); + if (in_range_p (tmp, 0, 63, 3)) { notethat ("LDSTii: dpregs = [ pregs + uimm6m4 ]\n"); @@ -2984,105 +3128,128 @@ asm_1: else if (in_range_p (tmp, -131072, 131071, 3)) { notethat ("LDSTidxI: [ pregs + imm18m4 ] = dpregs\n"); - $$ = LDSTIDXI (&$2, &$7, 1, 0, ispreg ? 1: 0, tmp); + $$ = LDSTIDXI (&$2, &$7, 1, 0, ispreg ? 1 : 0, tmp); } else - return yyerror ("Displacement out of range for store"); + return yyerror ("Displacement out of range"); } | REG ASSIGN W LBRACK REG plus_minus expr RBRACK xpmod { - if (IS_DREG ($1) && IS_PREG ($5) && IS_URANGE (4, $7, $6.r0, 2)) + Expr_Node *tmp = $7; + if (!IS_DREG ($1)) + return yyerror ("Dreg expected for destination operand"); + if (!IS_PREG ($5)) + return yyerror ("Preg expected in address"); + + if ($6.r0) + tmp = unary (Expr_Op_Type_NEG, tmp); + + if (IS_RELOC ($7)) + return yyerror ("Plain symbol used as offset"); + + if (in_range_p (tmp, 0, 30, 1)) { - notethat ("LDSTii: dregs = W [ pregs + uimm4s2 ] (.)\n"); - $$ = LDSTII (&$5, &$1, $7, 0, 1 << $9.r0); + notethat ("LDSTii: dregs = W [ pregs + uimm5m2 ] (.)\n"); + $$ = LDSTII (&$5, &$1, tmp, 0, 1 << $9.r0); } - else if (IS_DREG ($1) && IS_PREG ($5) && IS_RANGE(16, $7, $6.r0, 2)) + else if (in_range_p (tmp, -65536, 65535, 1)) { notethat ("LDSTidxI: dregs = W [ pregs + imm17m2 ] (.)\n"); - if ($6.r0) - neg_value ($7); - $$ = LDSTIDXI (&$5, &$1, 0, 1, $9.r0, $7); + $$ = LDSTIDXI (&$5, &$1, 0, 1, $9.r0, tmp); } else - return yyerror ("Bad register or constant for LOAD"); - } + return yyerror ("Displacement out of range"); + } | HALF_REG ASSIGN W LBRACK REG post_op RBRACK { + if (!IS_DREG ($1)) + return yyerror ("Dreg expected for source operand"); + if ($6.x0 == 2) + { + if (!IS_IREG ($5) && !IS_PREG ($5)) + return yyerror ("Ireg or Preg expected in address"); + } + else if (!IS_IREG ($5)) + return yyerror ("Ireg expected in address"); + if (IS_IREG ($5)) { - notethat ("dspLDST: dregs_half = W [ iregs ]\n"); + notethat ("dspLDST: dregs_half = W [ iregs ]\n"); $$ = DSPLDST(&$5, 1 + IS_H ($1), &$1, $6.x0, 0); } - else if ($6.x0 == 2 && IS_DREG ($1) && IS_PREG ($5)) + else { - notethat ("LDSTpmod: dregs_half = W [ pregs ]\n"); + notethat ("LDSTpmod: dregs_half = W [ pregs ]\n"); $$ = LDSTPMOD (&$5, &$1, &$5, 1 + IS_H ($1), 0); } - else - return yyerror ("Bad register or post_op for LOAD"); } | REG ASSIGN W LBRACK REG post_op RBRACK xpmod { - if (IS_DREG ($1) && IS_PREG ($5)) - { - notethat ("LDST: dregs = W [ pregs ] (.)\n"); - $$ = LDST (&$5, &$1, $6.x0, 1, $8.r0, 0); - } - else - return yyerror ("Bad register for LOAD"); + if (!IS_DREG ($1)) + return yyerror ("Dreg expected for destination operand"); + if (!IS_PREG ($5)) + return yyerror ("Preg expected in address"); + + notethat ("LDST: dregs = W [ pregs ] (.)\n"); + $$ = LDST (&$5, &$1, $6.x0, 1, $8.r0, 0); } | REG ASSIGN W LBRACK REG _PLUS_PLUS REG RBRACK xpmod { - if (IS_DREG ($1) && IS_PREG ($5) && IS_PREG ($7)) - { - notethat ("LDSTpmod: dregs = W [ pregs ++ pregs ] (.)\n"); - $$ = LDSTPMOD (&$5, &$1, &$7, 3, $9.r0); - } - else - return yyerror ("Bad register for LOAD"); + if (!IS_DREG ($1)) + return yyerror ("Dreg expected for destination operand"); + if (!IS_PREG ($5) || !IS_PREG ($7)) + return yyerror ("Preg expected in address"); + + notethat ("LDSTpmod: dregs = W [ pregs ++ pregs ] (.)\n"); + $$ = LDSTPMOD (&$5, &$1, &$7, 3, $9.r0); } | HALF_REG ASSIGN W LBRACK REG _PLUS_PLUS REG RBRACK { - if (IS_DREG ($1) && IS_PREG ($5) && IS_PREG ($7)) - { - notethat ("LDSTpmod: dregs_half = W [ pregs ++ pregs ]\n"); - $$ = LDSTPMOD (&$5, &$1, &$7, 1 + IS_H ($1), 0); - } - else - return yyerror ("Bad register for LOAD"); + if (!IS_DREG ($1)) + return yyerror ("Dreg expected for destination operand"); + if (!IS_PREG ($5) || !IS_PREG ($7)) + return yyerror ("Preg expected in address"); + + notethat ("LDSTpmod: dregs_half = W [ pregs ++ pregs ]\n"); + $$ = LDSTPMOD (&$5, &$1, &$7, 1 + IS_H ($1), 0); } | LBRACK REG post_op RBRACK ASSIGN REG { - if (IS_IREG ($2) && IS_DREG ($6)) + if (!IS_IREG ($2) && !IS_PREG ($2)) + return yyerror ("Ireg or Preg expected in address"); + else if (IS_IREG ($2) && !IS_DREG ($6)) + return yyerror ("Dreg expected for source operand"); + else if (IS_PREG ($2) && !IS_DREG ($6) && !IS_PREG ($6)) + return yyerror ("Dreg or Preg expected for source operand"); + + if (IS_IREG ($2)) { notethat ("dspLDST: [ iregs ] = dregs\n"); $$ = DSPLDST(&$2, 0, &$6, $3.x0, 1); } - else if (IS_PREG ($2) && IS_DREG ($6)) + else if (IS_DREG ($6)) { notethat ("LDST: [ pregs ] = dregs\n"); $$ = LDST (&$2, &$6, $3.x0, 0, 0, 1); } - else if (IS_PREG ($2) && IS_PREG ($6)) + else { notethat ("LDST: [ pregs ] = pregs\n"); $$ = LDST (&$2, &$6, $3.x0, 0, 1, 1); } - else - return yyerror ("Bad register for STORE"); } | LBRACK REG _PLUS_PLUS REG RBRACK ASSIGN REG { - if (! IS_DREG ($7)) - return yyerror ("Expected Dreg for last argument"); + if (!IS_DREG ($7)) + return yyerror ("Dreg expected for source operand"); if (IS_IREG ($2) && IS_MREG ($4)) { @@ -3095,62 +3262,76 @@ asm_1: $$ = LDSTPMOD (&$2, &$7, &$4, 0, 1); } else - return yyerror ("Bad register for STORE"); + return yyerror ("Preg ++ Preg or Ireg ++ Mreg expected in address"); } - + | W LBRACK REG _PLUS_PLUS REG RBRACK ASSIGN HALF_REG { if (!IS_DREG ($8)) - return yyerror ("Expect Dreg as last argument"); + return yyerror ("Dreg expected for source operand"); + if (IS_PREG ($3) && IS_PREG ($5)) { notethat ("LDSTpmod: W [ pregs ++ pregs ] = dregs_half\n"); $$ = LDSTPMOD (&$3, &$8, &$5, 1 + IS_H ($8), 1); } else - return yyerror ("Bad register for STORE"); + return yyerror ("Preg ++ Preg expected in address"); } | REG ASSIGN B LBRACK REG plus_minus expr RBRACK xpmod { - if (IS_DREG ($1) && IS_PREG ($5) && IS_RANGE(16, $7, $6.r0, 1)) + Expr_Node *tmp = $7; + if (!IS_DREG ($1)) + return yyerror ("Dreg expected for destination operand"); + if (!IS_PREG ($5)) + return yyerror ("Preg expected in address"); + + if ($6.r0) + tmp = unary (Expr_Op_Type_NEG, tmp); + + if (IS_RELOC ($7)) + return yyerror ("Plain symbol used as offset"); + + if (in_range_p (tmp, -32768, 32767, 0)) { notethat ("LDSTidxI: dregs = B [ pregs + imm16 ] (%c)\n", $9.r0 ? 'X' : 'Z'); - if ($6.r0) - neg_value ($7); - $$ = LDSTIDXI (&$5, &$1, 0, 2, $9.r0, $7); + $$ = LDSTIDXI (&$5, &$1, 0, 2, $9.r0, tmp); } else - return yyerror ("Bad register or value for LOAD"); + return yyerror ("Displacement out of range"); } | REG ASSIGN B LBRACK REG post_op RBRACK xpmod { - if (IS_DREG ($1) && IS_PREG ($5)) - { - notethat ("LDST: dregs = B [ pregs ] (%c)\n", - $8.r0 ? 'X' : 'Z'); - $$ = LDST (&$5, &$1, $6.x0, 2, $8.r0, 0); - } - else - return yyerror ("Bad register for LOAD"); + if (!IS_DREG ($1)) + return yyerror ("Dreg expected for destination operand"); + if (!IS_PREG ($5)) + return yyerror ("Preg expected in address"); + + notethat ("LDST: dregs = B [ pregs ] (%c)\n", + $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) && IS_IREG ($4) && IS_MREG ($6)) + if (!IS_DREG ($1)) + return yyerror ("Dreg expected for destination operand"); + + if (IS_IREG ($4) && IS_MREG ($6)) { notethat ("dspLDST: dregs = [ iregs ++ mregs ]\n"); $$ = DSPLDST(&$4, $6.regno & CODE_MASK, &$1, 3, 0); } - else if (IS_DREG ($1) && IS_PREG ($4) && IS_PREG ($6)) + else if (IS_PREG ($4) && IS_PREG ($6)) { notethat ("LDSTpmod: dregs = [ pregs ++ pregs ]\n"); $$ = LDSTPMOD (&$4, &$1, &$6, 0, 0); } else - return yyerror ("Bad register for LOAD"); + return yyerror ("Preg ++ Preg or Ireg ++ Mreg expected in address"); } | REG ASSIGN LBRACK REG plus_minus got_or_expr RBRACK @@ -3160,18 +3341,24 @@ asm_1: int isgot = IS_RELOC($6); if (!IS_PREG ($4)) - return yyerror ("Preg expected for indirect"); + return yyerror ("Preg expected in address"); if (!IS_DREG ($1) && !ispreg) - return yyerror ("Bad destination register for LOAD"); + return yyerror ("Dreg or Preg expected for destination operand"); + + if (tmp->type == Expr_Node_Reloc + && strcmp (tmp->value.s_value, + "_current_shared_library_p5_offset_") != 0) + return yyerror ("Plain symbol used as offset"); if ($5.r0) tmp = unary (Expr_Op_Type_NEG, tmp); - if(isgot){ + if (isgot) + { notethat ("LDSTidxI: dpregs = [ pregs + sym@got ]\n"); - $$ = LDSTIDXI (&$4, &$1, 0, 0, ispreg ? 1: 0, tmp); - } + $$ = LDSTIDXI (&$4, &$1, 0, 0, ispreg ? 1 : 0, tmp); + } else if (in_range_p (tmp, 0, 63, 3)) { notethat ("LDSTii: dpregs = [ pregs + uimm7m4 ]\n"); @@ -3186,26 +3373,34 @@ asm_1: else if (in_range_p (tmp, -131072, 131071, 3)) { notethat ("LDSTidxI: dpregs = [ pregs + imm18m4 ]\n"); - $$ = LDSTIDXI (&$4, &$1, 0, 0, ispreg ? 1: 0, tmp); - + $$ = LDSTIDXI (&$4, &$1, 0, 0, ispreg ? 1 : 0, tmp); + } else - return yyerror ("Displacement out of range for load"); + return yyerror ("Displacement out of range"); } | REG ASSIGN LBRACK REG post_op RBRACK { - if (IS_DREG ($1) && IS_IREG ($4)) + if (!IS_IREG ($4) && !IS_PREG ($4)) + return yyerror ("Ireg or Preg expected in address"); + else if (IS_IREG ($4) && !IS_DREG ($1)) + return yyerror ("Dreg expected in destination operand"); + else if (IS_PREG ($4) && !IS_DREG ($1) && !IS_PREG ($1) + && ($4.regno != REG_SP || !IS_ALLREG ($1) || $5.x0 != 0)) + return yyerror ("Dreg or Preg expected in destination operand"); + + if (IS_IREG ($4)) { notethat ("dspLDST: dregs = [ iregs ]\n"); $$ = DSPLDST (&$4, 0, &$1, $5.x0, 0); } - else if (IS_DREG ($1) && IS_PREG ($4)) + else if (IS_DREG ($1)) { notethat ("LDST: dregs = [ pregs ]\n"); $$ = LDST (&$4, &$1, $5.x0, 0, 0, 0); } - else if (IS_PREG ($1) && IS_PREG ($4)) + else if (IS_PREG ($1)) { if (REG_SAME ($1, $4) && $5.x0 != 2) return yyerror ("Pregs can't be same"); @@ -3213,13 +3408,11 @@ asm_1: notethat ("LDST: pregs = [ pregs ]\n"); $$ = LDST (&$4, &$1, $5.x0, 0, 1, 0); } - else if ($4.regno == REG_SP && IS_ALLREG ($1) && $5.x0 == 0) + else { notethat ("PushPopReg: allregs = [ SP ++ ]\n"); $$ = PUSHPOPREG (&$1, 0); } - else - return yyerror ("Bad register or value"); } @@ -3315,7 +3508,7 @@ asm_1: else return yyerror ("Bad constant for LINK"); } - + | UNLINK { notethat ("linkage: UNLINK\n"); @@ -3334,7 +3527,7 @@ asm_1: } else return yyerror ("Bad register or values for LSETUP"); - + } | LSETUP LPAREN expr COMMA expr RPAREN REG ASSIGN REG { @@ -3351,7 +3544,7 @@ asm_1: | 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"); @@ -3390,8 +3583,57 @@ asm_1: else return yyerror ("Bad register or values for LOOP"); } + +/* LOOP_BEGIN. */ + | LOOP_BEGIN NUMBER + { + Expr_Node_Value val; + val.i_value = $2; + Expr_Node *tmp = Expr_Node_Create (Expr_Node_Constant, val, NULL, NULL); + bfin_loop_attempt_create_label (tmp, 1); + if (!IS_RELOC (tmp)) + return yyerror ("Invalid expression in LOOP_BEGIN statement"); + bfin_loop_beginend (tmp, 1); + $$ = 0; + } + | LOOP_BEGIN expr + { + if (!IS_RELOC ($2)) + return yyerror ("Invalid expression in LOOP_BEGIN statement"); + + bfin_loop_beginend ($2, 1); + $$ = 0; + } + +/* LOOP_END. */ + | LOOP_END NUMBER + { + Expr_Node_Value val; + val.i_value = $2; + Expr_Node *tmp = Expr_Node_Create (Expr_Node_Constant, val, NULL, NULL); + bfin_loop_attempt_create_label (tmp, 1); + if (!IS_RELOC (tmp)) + return yyerror ("Invalid expression in LOOP_END statement"); + bfin_loop_beginend (tmp, 0); + $$ = 0; + } + | LOOP_END expr + { + if (!IS_RELOC ($2)) + return yyerror ("Invalid expression in LOOP_END statement"); + + bfin_loop_beginend ($2, 0); + $$ = 0; + } + /* pseudoDEBUG. */ + | ABORT + { + notethat ("psedoDEBUG: ABORT\n"); + $$ = bfin_gen_pseudodbg (3, 3, 0); + } + | DBG { notethat ("pseudoDEBUG: DBG\n"); @@ -3405,7 +3647,7 @@ asm_1: | DBG REG { notethat ("pseudoDEBUG: DBG allregs\n"); - $$ = bfin_gen_pseudodbg (0, $2.regno & CODE_MASK, $2.regno & CLASS_MASK); + $$ = bfin_gen_pseudodbg (0, $2.regno & CODE_MASK, ($2.regno & CLASS_MASK) >> 4); } | DBGCMPLX LPAREN REG RPAREN @@ -3413,33 +3655,54 @@ asm_1: if (!IS_DREG ($3)) return yyerror ("Dregs expected"); notethat ("pseudoDEBUG: DBGCMPLX (dregs )\n"); - $$ = bfin_gen_pseudodbg (3, 6, $3.regno & CODE_MASK); + $$ = bfin_gen_pseudodbg (3, 6, ($3.regno & CODE_MASK) >> 4); } - + | DBGHALT { notethat ("psedoDEBUG: DBGHALT\n"); $$ = bfin_gen_pseudodbg (3, 5, 0); } + | HLT + { + notethat ("psedoDEBUG: HLT\n"); + $$ = bfin_gen_pseudodbg (3, 4, 0); + } + | DBGA LPAREN HALF_REG COMMA expr RPAREN { - notethat ("pseudodbg_assert: DBGA (dregs_lo , uimm16 )\n"); + notethat ("pseudodbg_assert: DBGA (regs_lo/hi , uimm16 )\n"); $$ = bfin_gen_pseudodbg_assert (IS_H ($3), &$3, uimm16 ($5)); } - + | DBGAH LPAREN REG COMMA expr RPAREN { - notethat ("pseudodbg_assert: DBGAH (dregs , uimm16 )\n"); + notethat ("pseudodbg_assert: DBGAH (regs , uimm16 )\n"); $$ = bfin_gen_pseudodbg_assert (3, &$3, uimm16 ($5)); } | DBGAL LPAREN REG COMMA expr RPAREN { - notethat ("psedodbg_assert: DBGAL (dregs , uimm16 )\n"); + notethat ("psedodbg_assert: DBGAL (regs , uimm16 )\n"); $$ = bfin_gen_pseudodbg_assert (2, &$3, uimm16 ($5)); } + | OUTC expr + { + if (!IS_UIMM ($2, 8)) + return yyerror ("Constant out of range"); + notethat ("psedodbg_assert: OUTC uimm8\n"); + $$ = bfin_gen_pseudochr (uimm8 ($2)); + } + + | OUTC REG + { + if (!IS_DREG ($2)) + return yyerror ("Dregs expected"); + notethat ("psedodbg_assert: OUTC dreg\n"); + $$ = bfin_gen_pseudodbg (2, $2.regno & CODE_MASK, 0); + } ; @@ -3513,7 +3776,7 @@ sco: $$.x0 = 1; } | SCO - { + { $$.s0 = 1; $$.x0 = 1; } @@ -3803,7 +4066,7 @@ min_max: $$.r0 = 0; } ; - + op_bar_op: _PLUS_BAR_PLUS { @@ -3924,8 +4187,8 @@ b3_op: post_op: { $$.x0 = 2; - } - | _PLUS_PLUS + } + | _PLUS_PLUS { $$.x0 = 0; } @@ -3961,6 +4224,11 @@ a_plusassign: assign_macfunc: REG ASSIGN REG_A { + if (IS_A1 ($3) && IS_EVEN ($1)) + return yyerror ("Cannot move A1 to even register"); + else if (!IS_A1 ($3) && !IS_EVEN ($1)) + return yyerror ("Cannot move A0 to odd register"); + $$.w = 1; $$.P = 1; $$.n = IS_A1 ($3); @@ -3968,11 +4236,6 @@ assign_macfunc: $$.dst = $1; $$.s0.regno = 0; $$.s1.regno = 0; - - if (IS_A1 ($3) && IS_EVEN ($1)) - return yyerror ("Cannot move A1 to even register"); - else if (!IS_A1 ($3) && !IS_EVEN ($1)) - return yyerror ("Cannot move A0 to odd register"); } | a_macfunc { @@ -3982,6 +4245,11 @@ assign_macfunc: } | REG ASSIGN LPAREN a_macfunc RPAREN { + if ($4.n && IS_EVEN ($1)) + return yyerror ("Cannot move A1 to even register"); + else if (!$4.n && !IS_EVEN ($1)) + return yyerror ("Cannot move A0 to odd register"); + $$ = $4; $$.w = 1; $$.P = 1; @@ -3990,6 +4258,11 @@ assign_macfunc: | HALF_REG ASSIGN LPAREN a_macfunc RPAREN { + if ($4.n && !IS_H ($1)) + return yyerror ("Cannot move A1 to low half of register"); + else if (!$4.n && IS_H ($1)) + return yyerror ("Cannot move A0 to high half of register"); + $$ = $4; $$.w = 1; $$.P = 0; @@ -3998,6 +4271,11 @@ assign_macfunc: | HALF_REG ASSIGN REG_A { + if (IS_A1 ($3) && !IS_H ($1)) + return yyerror ("Cannot move A1 to low half of register"); + else if (!IS_A1 ($3) && IS_H ($1)) + return yyerror ("Cannot move A0 to high half of register"); + $$.w = 1; $$.P = 0; $$.n = IS_A1 ($3); @@ -4005,11 +4283,6 @@ assign_macfunc: $$.dst = $1; $$.s0.regno = 0; $$.s1.regno = 0; - - if (IS_A1 ($3) && !IS_H ($1)) - return yyerror ("Cannot move A1 to low half of register"); - else if (!IS_A1 ($3) && IS_H ($1)) - return yyerror ("Cannot move A0 to high half of register"); } ; @@ -4072,27 +4345,27 @@ cc_op: ccstat: CCREG cc_op STATUS_REG { - $$.r0 = $3.regno; - $$.x0 = $2.r0; - $$.s0 = 0; + $$.r0 = $3.regno; + $$.x0 = $2.r0; + $$.s0 = 0; } | CCREG cc_op V { - $$.r0 = 0x18; - $$.x0 = $2.r0; - $$.s0 = 0; + $$.r0 = 0x18; + $$.x0 = $2.r0; + $$.s0 = 0; } | STATUS_REG cc_op CCREG { - $$.r0 = $1.regno; - $$.x0 = $2.r0; - $$.s0 = 1; + $$.r0 = $1.regno; + $$.x0 = $2.r0; + $$.s0 = 1; } | V cc_op CCREG { - $$.r0 = 0x18; - $$.x0 = $2.r0; - $$.s0 = 1; + $$.r0 = 0x18; + $$.x0 = $2.r0; + $$.s0 = 1; } ; @@ -4192,7 +4465,7 @@ expr_1: expr_1 STAR expr_1 } | 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 { @@ -4210,7 +4483,7 @@ expr_1: expr_1 STAR expr_1 { $$ = binary (Expr_Op_Type_BOR, $1, $3); } - | eterm + | eterm { $$ = $1; } @@ -4229,17 +4502,17 @@ mkexpr (int x, SYMBOL_T s) } static int -value_match (Expr_Node *expr, int sz, int sign, int mul, int issigned) +value_match (Expr_Node *exp, int sz, int sign, int mul, int issigned) { - long umax = (1L << sz) - 1; - long min = -1L << (sz - 1); - long max = (1L << (sz - 1)) - 1; - - long v = EXPR_VALUE (expr); + 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; } @@ -4257,7 +4530,7 @@ value_match (Expr_Node *expr, int sz, int sign, int mul, int issigned) #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); @@ -4276,48 +4549,48 @@ binary (Expr_Op_Type op, Expr_Node *x, Expr_Node *y) { 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; default: - error ("%s:%d: Internal compiler error\n", __FILE__, __LINE__); + error ("%s:%d: Internal assembler error\n", __FILE__, __LINE__); } return x; } @@ -4350,20 +4623,20 @@ binary (Expr_Op_Type op, Expr_Node *x, Expr_Node *y) } 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: x->value.i_value = ~x->value.i_value; break; default: - error ("%s:%d: Internal compiler error\n", __FILE__, __LINE__); + error ("%s:%d: Internal assembler error\n", __FILE__, __LINE__); } return x; } @@ -4378,7 +4651,7 @@ unary (Expr_Op_Type op, Expr_Node *x) int debug_codeselection = 0; static void -notethat (char *format, ...) +notethat (const char *format, ...) { va_list ap; va_start (ap, format);