Kaynağa Gözat

Added required modifications

Andrea Gussoni 8 yıl önce
ebeveyn
işleme
898fdd57dc
2 değiştirilmiş dosya ile 59 ekleme ve 0 silme
  1. 54 0
      acse/axe_expressions.c
  2. 5 0
      acse/axe_expressions.h

+ 54 - 0
acse/axe_expressions.c

@@ -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);
+}

+ 5 - 0
acse/axe_expressions.h

@@ -50,4 +50,9 @@ extern t_axe_expression handle_bin_numeric_op (t_program_infos *program
 extern t_axe_expression handle_binary_comparison (t_program_infos *program
          , t_axe_expression exp1, t_axe_expression exp2, int condition);
 
+extern t_axe_expression handle_brange_op (t_program_infos *program,
+                                          t_axe_expression op,
+                                          t_axe_expression lo,
+                                          t_axe_expression hi);
+
 #endif