|
@@ -296,3 +296,57 @@ t_axe_expression handle_binary_comparison (t_program_infos *program
|
|
|
/* return the new expression */
|
|
|
return create_expression (output_register, REGISTER);
|
|
|
}
|
|
|
+
|
|
|
+t_axe_expression handle_brange_op (t_program_infos *program,
|
|
|
+ t_axe_expression op,
|
|
|
+ t_axe_expression lo,
|
|
|
+ t_axe_expression hi)
|
|
|
+{
|
|
|
+ int is_lo_const = lo.expression_type == IMMEDIATE;
|
|
|
+ int is_hi_const = hi.expression_type == IMMEDIATE;
|
|
|
+
|
|
|
+ if ((is_lo_const && lo.value < 0) || (is_hi_const && hi.value > 31)
|
|
|
+ || (is_lo_const && is_hi_const && lo.value > hi.value))
|
|
|
+ return create_expression(0, IMMEDIATE);
|
|
|
+
|
|
|
+ t_axe_label *invalid_label = NULL;
|
|
|
+
|
|
|
+ if (!is_lo_const || !is_hi_const) {
|
|
|
+ invalid_label = newLabel(program);
|
|
|
+
|
|
|
+ if (!is_lo_const) {
|
|
|
+ t_axe_expression zero = create_expression(0, IMMEDIATE);
|
|
|
+ handle_binary_comparison(program, lo, zero, _LT_);
|
|
|
+ gen_bne_instruction(program, invalid_label, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!is_hi_const) {
|
|
|
+ t_axe_expression max = create_expression(31, IMMEDIATE);
|
|
|
+ handle_binary_comparison(program, hi, max, _GT_);
|
|
|
+ gen_bne_instruction(program, invalid_label, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ handle_binary_comparison(program, lo, hi, _GT_);
|
|
|
+ gen_bne_instruction(program, invalid_label, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ t_axe_expression one = create_expression(1, IMMEDIATE);
|
|
|
+ t_axe_expression output = handle_bin_numeric_op(program, op, lo, SHR);
|
|
|
+ t_axe_expression mask = handle_bin_numeric_op(program, hi, lo, SUB);
|
|
|
+ mask = handle_bin_numeric_op(program, mask, one, ADD);
|
|
|
+ mask = handle_bin_numeric_op(program, one, mask, SHL);
|
|
|
+ mask = handle_bin_numeric_op(program, mask, one, SUB);
|
|
|
+ output = handle_bin_numeric_op(program, output, mask, ANDB);
|
|
|
+
|
|
|
+ if (!invalid_label)
|
|
|
+ return output;
|
|
|
+
|
|
|
+ int res_reg = getNewRegister(program);
|
|
|
+ gen_orbi_instruction(program, res_reg, output.value, 0);
|
|
|
+ t_axe_label *end_label = newLabel(program);
|
|
|
+ gen_bt_instruction(program, end_label, 0);
|
|
|
+ assignLabel(program, invalid_label);
|
|
|
+ gen_orbi_instruction(program, res_reg, REG_0, 0);
|
|
|
+ assignLabel(program, end_label);
|
|
|
+ return create_expression(res_reg, REGISTER);
|
|
|
+}
|