|
@@ -129,6 +129,8 @@ t_io_infos *file_infos; /* input and output files used by the compiler */
|
|
|
%token <intval> TYPE
|
|
|
%token <svalue> IDENTIFIER
|
|
|
%token <intval> NUMBER
|
|
|
+%token <label> DOLLAR
|
|
|
+%token <label> AT
|
|
|
|
|
|
%type <expr> exp
|
|
|
%type <decl> declaration
|
|
@@ -147,6 +149,7 @@ t_io_infos *file_infos; /* input and output files used by the compiler */
|
|
|
%left AND_OP
|
|
|
%left EQ NOTEQ
|
|
|
%left LT GT LTEQ GTEQ
|
|
|
+%left DOLLAR AT
|
|
|
%left SHL_OP SHR_OP
|
|
|
%left MINUS PLUS
|
|
|
%left MUL_OP DIV_OP
|
|
@@ -565,6 +568,53 @@ exp: NUMBER { $$ = create_expression ($1, IMMEDIATE); }
|
|
|
(program, exp_r0, $2, SUB);
|
|
|
}
|
|
|
}
|
|
|
+ | exp DOLLAR exp AT exp {
|
|
|
+ int e_c;
|
|
|
+ if ($5.expression_type != IMMEDIATE)
|
|
|
+ yyerror();
|
|
|
+ if ($5.value < 0)
|
|
|
+ yyerror();
|
|
|
+ if ($5.value > 32)
|
|
|
+ e_c = 0;
|
|
|
+ else
|
|
|
+ e_c = 32 - $5.value;
|
|
|
+
|
|
|
+ int r_e2 = gen_load_immediate(program, 0);
|
|
|
+ int r_index = gen_load_immediate(program, e_c);
|
|
|
+
|
|
|
+ $4 = newLabel(program);
|
|
|
+ $2 = assignNewLabel(program);
|
|
|
+
|
|
|
+ gen_beq_instruction(program, $4, 0);
|
|
|
+ gen_shli_instruction(program, r_e2, r_e2, 1);
|
|
|
+ gen_addi_instruction(program, r_e2, r_e2, 1);
|
|
|
+ gen_subi_instruction(program, r_index, r_index, 1);
|
|
|
+
|
|
|
+ gen_bt_instruction(program, $2, 0);
|
|
|
+ assignLabel(program, $4);
|
|
|
+ int r_e1 = getNewRegister(program);
|
|
|
+ gen_notb_instruction(program, r_e1, r_e2);
|
|
|
+
|
|
|
+ if ($1.expression_type == IMMEDIATE)
|
|
|
+ gen_andb_instruction(program, r_e1, r_e1,
|
|
|
+ gen_load_immediate(program, $1.value),
|
|
|
+ CG_DIRECT_ALL);
|
|
|
+ else
|
|
|
+ gen_andb_instruction(program, r_e1, r_e1, $1.value,
|
|
|
+ CG_DIRECT_ALL);
|
|
|
+
|
|
|
+ if ($3.expression_type == IMMEDIATE)
|
|
|
+ gen_andb_instruction(program, r_e2, r_e2,
|
|
|
+ gen_load_immediate(program, $3.value),
|
|
|
+ CG_DIRECT_ALL);
|
|
|
+ else
|
|
|
+ gen_andb_instruction(program, r_e2, r_e2, $3.value,
|
|
|
+ CG_DIRECT_ALL);
|
|
|
+
|
|
|
+ gen_orb_instruction(program, r_e1, r_e1, r_e2,
|
|
|
+ CG_DIRECT_ALL);
|
|
|
+ $$ = create_expression(r_e1, REGISTER);
|
|
|
+ }
|
|
|
;
|
|
|
|
|
|
%%
|