<div dir="ltr">Hi,<div><br></div><div>This part of the change is available in rotd-2017-04-11.  Everyone will</div><div>need to update; I'll commit the second part next week.</div><div><br></div><div>Julien.<br><div class="gmail_extra"><br><div class="gmail_quote">On 11 April 2017 at 13:07, Julien Fischer <span dir="ltr"><<a href="mailto:jfischer@opturion.com" target="_blank">jfischer@opturion.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
The following will need to bootstrap before the new oprations can be<br>
made available in the standard library -- I'll commit the second part<br>
some time next week.  Also, there's been some discussion on of the<br>
operand types and semantics of the shift operations -- the outcome of<br>
those discussions won't affect the code below.<br>
<br>
---------------------<br>
<br>
Add more builtin ops on uints (part 1).<br>
<br>
compiler/builtin_ops.m:<br>
     Add unchecked left and right shifts for uints as well<br>
     as the reverse modes of addition and subtraction.<br>
<br>
library/uint.m:<br>
     Add commented out mode declarations for addition and<br>
     subtraction; they can be uncommented once the above<br>
     has bootstrapped.<br>
<br>
compiler/bytecode.m:<br>
compiler/c_util.m:<br>
compiler/erl_call_gen.m:<br>
compiler/llds.m:<br>
compiler/llds_out_data.m:<br>
compiler/ml_global_data.m:<br>
compiler/mlds_to_c.m:<br>
compiler/mlds_to_cs.m:<br>
compiler/mlds_to_java.m:<br>
compiler/opt_debug.m:<br>
     Conform to the above changes.<br>
<br>
Julien.<br>
<br>
diff --git a/compiler/builtin_ops.m b/compiler/builtin_ops.m<br>
index 356f0b8..e19eee9 100644<br>
--- a/compiler/builtin_ops.m<br>
+++ b/compiler/builtin_ops.m<br>
@@ -111,6 +111,9 @@<br>
     ;       uint_bitwise_or<br>
     ;       uint_bitwise_xor<br>
<br>
+    ;       uint_unchecked_left_shift<br>
+    ;       uint_unchecked_right_shift<br>
+<br>
     ;       float_plus      %  XXX the integer versions use different names.<br>
     ;       float_minus     %  E.g add instead of plus etc.<br>
     ;       float_times<br>
@@ -397,15 +400,43 @@ builtin_translation(ModuleName<wbr>, PredName, ProcNum, Args, Code) :-<br>
             ProcNum = 0,<br>
             Args = [X, Y],<br>
             Code = assign(Y, unary(uint_bitwise_complement, leaf(X)))<br>
-    ;<br>
-            ( PredName = "+", ArithOp = uint_add<br>
-            ; PredName = "-", ArithOp = uint_sub<br>
-            ; PredName = "*", ArithOp = uint_mul<br>
+        ;<br>
+            PredName = "+",<br>
+            Args = [X, Y, Z],<br>
+            (<br>
+                ProcNum = 0,<br>
+                Code = assign(Z, binary(uint_add, leaf(X), leaf(Y)))<br>
+            ;<br>
+                ProcNum = 1,<br>
+                Code = assign(X, binary(uint_sub, leaf(Z), leaf(Y)))<br>
+            ;<br>
+                ProcNum = 2,<br>
+                Code = assign(Y, binary(uint_sub, leaf(Z), leaf(X)))<br>
+            )<br>
+        ;<br>
+            PredName = "-",<br>
+            Args = [X, Y, Z],<br>
+            (<br>
+                ProcNum = 0,<br>
+                Code = assign(Z, binary(int_sub, leaf(X), leaf(Y)))<br>
+            ;<br>
+                ProcNum = 1,<br>
+                Code = assign(X, binary(uint_add, leaf(Y), leaf(Z)))<br>
+            ;<br>
+                ProcNum = 2,<br>
+                Code = assign(Y, binary(uint_sub, leaf(X), leaf(Z)))<br>
+            )<br>
+        ;<br>
+            ( PredName = "*", ArithOp = uint_mul<br>
             ; PredName = "unchecked_quotient", ArithOp = uint_div<br>
             ; PredName = "unchecked_rem", ArithOp = uint_mod<br>
             ; PredName = "/\\", ArithOp = uint_bitwise_and<br>
             ; PredName = "\\/", ArithOp = uint_bitwise_or<br>
             ; PredName = "xor", ArithOp = uint_bitwise_xor<br>
+            ; PredName = "unchecked_left_shift",<br>
+                ArithOp = uint_unchecked_left_shift<br>
+            ; PredName = "unchecked_right_shift",<br>
+                ArithOp = uint_unchecked_right_shift<br>
             ),<br>
             ProcNum = 0,<br>
             Args = [X, Y, Z],<br>
diff --git a/compiler/bytecode.m b/compiler/bytecode.m<br>
index 21af01a..5dc8d79 100644<br>
--- a/compiler/bytecode.m<br>
+++ b/compiler/bytecode.m<br>
@@ -1090,6 +1090,8 @@ binop_code(uint_mod,                55).<br>
 binop_code(uint_bitwise_and,        56).<br>
 binop_code(uint_bitwise_or,         57).<br>
 binop_code(uint_bitwise_xor,        58).<br>
+binop_code(uint_unchecked_lef<wbr>t_shift, 59).<br>
+binop_code(uint_unchecked_rig<wbr>ht_shift, 60).<br>
<br>
 :- pred binop_debug(binary_op::in, string::out) is det.<br>
<br>
@@ -1152,6 +1154,8 @@ binop_debug(uint_mod,               "uint_mod").<br>
 binop_debug(uint_bitwise_and,<wbr>       "uint_bitwise_and").<br>
 binop_debug(uint_bitwise_or,        "uint_bitwise_or").<br>
 binop_debug(uint_bitwise_xor,<wbr>       "uint_bitwise_xor").<br>
+binop_debug(uint_unchecked_le<wbr>ft_shift, "uint_unchecked_left_shift").<br>
+binop_debug(uint_unchecked_ri<wbr>ght_shift, "uint_unchecked_right_shift").<br>
<br>
 :- pred unop_code(unary_op::in, int::out) is det.<br>
<br>
diff --git a/compiler/c_util.m b/compiler/c_util.m<br>
index 90fb6a1..4f25295 100644<br>
--- a/compiler/c_util.m<br>
+++ b/compiler/c_util.m<br>
@@ -855,6 +855,8 @@ binop_category_string(uint_mod<wbr>, uint_binary_infix_binop, "%").<br>
 binop_category_string(uint_bi<wbr>twise_and, uint_binary_infix_binop, "&").<br>
 binop_category_string(uint_bi<wbr>twise_or, uint_binary_infix_binop, "|").<br>
 binop_category_string(uint_bi<wbr>twise_xor, uint_binary_infix_binop, "^").<br>
+binop_category_string(uint_un<wbr>checked_left_shift, uint_binary_infix_binop, "<<").<br>
+binop_category_string(uint_un<wbr>checked_right_shift, uint_binary_infix_binop, ">>").<br>
<br>
 binop_category_string(float_p<wbr>lus, float_arith_binop, "+").<br>
 binop_category_string(float_m<wbr>inus, float_arith_binop, "-").<br>
diff --git a/compiler/erl_call_gen.m b/compiler/erl_call_gen.m<br>
index 194d515..2efea95 100644<br>
--- a/compiler/erl_call_gen.m<br>
+++ b/compiler/erl_call_gen.m<br>
@@ -566,6 +566,8 @@ std_binop_to_elds(StdBinOp, EldsBinOp) :-<br>
         ; StdBinOp = uint_bitwise_and,      EldsBinOp = elds.band<br>
         ; StdBinOp = uint_bitwise_or,       EldsBinOp = elds.bor<br>
         ; StdBinOp = uint_bitwise_xor,      EldsBinOp = elds.bxor<br>
+        ; StdBinOp = uint_unchecked_left_shift, EldsBinOp = elds.bsl<br>
+        ; StdBinOp = uint_unchecked_right_shift, EldsBinOp = elds.bsr<br>
         )<br>
     ).<br>
<br>
diff --git a/compiler/llds.m b/compiler/llds.m<br>
index a6366eb..02df86c 100644<br>
--- a/compiler/llds.m<br>
+++ b/compiler/llds.m<br>
@@ -1769,6 +1769,8 @@ binop_return_type(uint_mod, lt_unsigned).<br>
 binop_return_type(uint_bitwis<wbr>e_and, lt_unsigned).<br>
 binop_return_type(uint_bitwis<wbr>e_or, lt_unsigned).<br>
 binop_return_type(uint_bitwis<wbr>e_xor, lt_unsigned).<br>
+binop_return_type(uint_unchec<wbr>ked_left_shift, lt_unsigned).<br>
+binop_return_type(uint_unchec<wbr>ked_right_shift, lt_unsigned).<br>
<br>
 register_type(reg_r, lt_word).<br>
 register_type(reg_f, lt_float).<br>
diff --git a/compiler/llds_out_data.m b/compiler/llds_out_data.m<br>
index f214136..bbcab36 100644<br>
--- a/compiler/llds_out_data.m<br>
+++ b/compiler/llds_out_data.m<br>
@@ -1024,6 +1024,8 @@ output_rval(Info, Rval, !IO) :-<br>
             ; Op = uint_bitwise_and, OpStr = "&"<br>
             ; Op = uint_bitwise_or, OpStr = "|"<br>
             ; Op = uint_bitwise_xor, OpStr = "^"<br>
+            ; Op = uint_unchecked_left_shift, OpStr = "<<"<br>
+            ; Op = uint_unchecked_right_shift, OpStr = ">>"<br>
             ),<br>
             io.write_string("(", !IO),<br>
             output_rval_as_type(Info, SubRvalA, lt_unsigned, !IO),<br>
diff --git a/compiler/ml_global_data.m b/compiler/ml_global_data.m<br>
index 0bd2825..3a2776b 100644<br>
--- a/compiler/ml_global_data.m<br>
+++ b/compiler/ml_global_data.m<br>
@@ -606,6 +606,8 @@ ml_specialize_generic_array_bi<wbr>nop(Op, IsFloat) :-<br>
         ; Op = uint_bitwise_and<br>
         ; Op = uint_bitwise_or<br>
         ; Op = uint_bitwise_xor<br>
+        ; Op = uint_unchecked_left_shift<br>
+        ; Op = uint_unchecked_right_shift<br>
         ; Op = float_eq<br>
         ; Op = float_ne<br>
         ; Op = float_lt<br>
diff --git a/compiler/mlds_to_c.m b/compiler/mlds_to_c.m<br>
index 2bebf57..070027e 100644<br>
--- a/compiler/mlds_to_c.m<br>
+++ b/compiler/mlds_to_c.m<br>
@@ -4615,6 +4615,8 @@ mlds_output_binop(Opts, Op, X, Y, !IO) :-<br>
         ; Op = uint_bitwise_and, OpStr = "&"<br>
         ; Op = uint_bitwise_or, OpStr = "|"<br>
         ; Op = uint_bitwise_xor, OpStr = "^"<br>
+        ; Op = uint_unchecked_left_shift, OpStr = "<<"<br>
+        ; Op = uint_unchecked_right_shift, OpStr = ">>"<br>
         ),<br>
         io.write_string("(", !IO),<br>
         mlds_output_rval_as_op_arg(Op<wbr>ts, X, !IO),<br>
diff --git a/compiler/mlds_to_cs.m b/compiler/mlds_to_cs.m<br>
index 6ce2f7e..70b0aa0 100644<br>
--- a/compiler/mlds_to_cs.m<br>
+++ b/compiler/mlds_to_cs.m<br>
@@ -3797,6 +3797,8 @@ output_binop(Info, Op, X, Y, !IO) :-<br>
         ; Op = uint_bitwise_and<br>
         ; Op = uint_bitwise_or<br>
         ; Op = uint_bitwise_xor<br>
+        ; Op = uint_unchecked_left_shift<br>
+        ; Op = uint_unchecked_right_shift<br>
         ; Op = float_plus<br>
         ; Op = float_minus<br>
         ; Op = float_times<br>
@@ -3859,6 +3861,8 @@ output_binary_op(Op, !IO) :-<br>
         ; Op = uint_bitwise_and, OpStr = "&"<br>
         ; Op = uint_bitwise_or, OpStr = "|"<br>
         ; Op = uint_bitwise_xor, OpStr = "^"<br>
+        ; Op = uint_unchecked_left_shift, OpStr = "<<"<br>
+        ; Op = uint_unchecked_right_shift, OpStr = ">>"<br>
<br>
         ; Op = float_eq, OpStr = "=="<br>
         ; Op = float_ne, OpStr = "!="<br>
diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m<br>
index d915d0f..6c674b3 100644<br>
--- a/compiler/mlds_to_java.m<br>
+++ b/compiler/mlds_to_java.m<br>
@@ -5205,6 +5205,8 @@ output_binop(Info, Op, X, Y, !IO) :-<br>
         ; Op = uint_bitwise_and<br>
         ; Op = uint_bitwise_or<br>
         ; Op = uint_bitwise_xor<br>
+        ; Op = uint_unchecked_left_shift<br>
+        ; Op = uint_unchecked_right_shift<br>
         ),<br>
         io.write_string("(", !IO),<br>
         output_rval(Info, X, !IO),<br>
@@ -5305,6 +5307,8 @@ output_binary_op(Op, !IO) :-<br>
         ; Op = uint_bitwise_and, OpStr = "&"<br>
         ; Op = uint_bitwise_or, OpStr = "|"<br>
         ; Op = uint_bitwise_xor, OpStr = "^"<br>
+        ; Op = uint_unchecked_left_shift, OpStr = "<<"<br>
+        ; Op = uint_unchecked_right_shift, OpStr = ">>>"<br>
<br>
         ; Op = float_eq, OpStr = "=="<br>
         ; Op = float_ne, OpStr = "!="<br>
diff --git a/compiler/opt_debug.m b/compiler/opt_debug.m<br>
index 1458e8a..40ee7ca 100644<br>
--- a/compiler/opt_debug.m<br>
+++ b/compiler/opt_debug.m<br>
@@ -870,6 +870,8 @@ dump_binop(uint_mod) = "uint%".<br>
 dump_binop(uint_bitwise_and) = "uint&".<br>
 dump_binop(uint_bitwise_or) = "uint|".<br>
 dump_binop(uint_bitwise_xor) = "uint^".<br>
+dump_binop(uint_unchecked_lef<wbr>t_shift) = "uint_unchecked<<".<br>
+dump_binop(uint_unchecked_rig<wbr>ht_shift) = "uint_unchecked>>".<br>
 dump_binop(float_plus) = "fl+".<br>
 dump_binop(float_minus) = "fl-".<br>
 dump_binop(float_times) = "fl*".<br>
diff --git a/library/uint.m b/library/uint.m<br>
index 9d79531..5bce93f 100644<br>
--- a/library/uint.m<br>
+++ b/library/uint.m<br>
@@ -53,11 +53,17 @@<br>
<br>
     % Addition.<br>
     %<br>
-:- func (uint::in) + (uint::in) = (uint::uo) is det.<br>
+:- func uint + int = uint.<br>
+:- mode in   + in  = uo is det.<br>
+%:- mode uo   + in  = in is det.<br>
+%:- mode in   + uo  = in is det.<br>
<br>
     % Subtraction.<br>
     %<br>
-:- func (uint::in) - (uint::in) = (uint::uo) is det.<br>
+:- func uint - uint = uint.<br>
+:- mode in   - in   = uo is det.<br>
+%:- mode uo   - in   = in is det.<br>
+%:- mode in   - uo   = in is det.<br>
<br>
     % Multiplication.<br>
     %<br>
</blockquote></div><br></div></div></div>