changeset 15141:6ea86e1d0f5f

Support +=, -=, *=, ect. in JIT * pt-jit.cc (jit-convert::visit_simple_assignment): Support more assignment operators. * ov.cc (octave_value::assign_op_to_binary_op): New function. * ov.h (octave_value::assign_op_to_binary_op): New declaration.
author Max Brister <max@2bass.com>
date Fri, 10 Aug 2012 12:23:32 -0500
parents eeaaac7c86b6
children 4388f6518440
files src/interp-core/pt-jit.cc src/octave-value/ov.cc src/octave-value/ov.h
diffstat 3 files changed, 60 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/interp-core/pt-jit.cc
+++ b/src/interp-core/pt-jit.cc
@@ -607,12 +607,20 @@
 void
 jit_convert::visit_simple_assignment (tree_simple_assignment& tsa)
 {
-  if (tsa.op_type () != octave_value::op_asn_eq)
-    throw jit_fail_exception ("Unsupported assign");
-
-  // resolve rhs
   tree_expression *rhs = tsa.right_hand_side ();
   jit_value *rhsv = visit (rhs);
+  octave_value::assign_op op = tsa.op_type ();
+
+  if (op != octave_value::op_asn_eq)
+    {
+      // do the equivlent binary operation, then assign. This is always correct,
+      // but isn't always optimal.
+      tree_expression *lhs = tsa.left_hand_side ();
+      jit_value *lhsv = visit (lhs);
+      octave_value::binary_op bop = octave_value::assign_op_to_binary_op (op);
+      const jit_operation& fn = jit_typeinfo::binary_op (bop);
+      rhsv = create_checked (fn, lhsv, rhsv);
+    }
 
   result = do_assign (tsa.left_hand_side (), rhsv);
 }
@@ -1948,4 +1956,11 @@
 %! endfor
 %! assert (m == sin ([1  2 3]));
 
+%!test
+%! i = 0;
+%! while i < 10
+%!   i += 1;
+%! endwhile
+%! assert (i == 10);
+
 */
--- a/src/octave-value/ov.cc
+++ b/src/octave-value/ov.cc
@@ -483,6 +483,45 @@
   return retval;
 }
 
+octave_value::binary_op
+octave_value::assign_op_to_binary_op (assign_op op)
+{
+  switch (op)
+    {
+    case op_add_eq:
+      return op_add;
+    case op_sub_eq:
+      return op_sub;
+    case op_mul_eq:
+      return op_mul;
+    case op_div_eq:
+      return op_div;
+    case op_ldiv_eq:
+      return op_ldiv;
+    case op_pow_eq:
+      return op_pow;
+    case op_lshift_eq:
+      return op_lshift;
+    case op_rshift_eq:
+      return op_rshift;
+    case op_el_mul_eq:
+      return op_el_mul;
+    case op_el_div_eq:
+      return op_el_div;
+    case op_el_ldiv_eq:
+      return op_el_ldiv;
+    case op_el_pow_eq:
+      return op_el_pow;
+    case op_el_and_eq:
+      return op_el_and;
+    case op_el_or_eq:
+      return op_el_or;
+    default:
+      return unknown_binary_op;
+    }
+
+}
+
 octave_value::assign_op
 octave_value::binary_op_to_assign_op (binary_op op)
 {
--- a/src/octave-value/ov.h
+++ b/src/octave-value/ov.h
@@ -145,6 +145,8 @@
     unknown_assign_op
   };
 
+  static binary_op assign_op_to_binary_op (assign_op);
+
   static assign_op binary_op_to_assign_op (binary_op);
 
   static std::string unary_op_as_string (unary_op);