diff -r 4a0654b18dbe acse/Acse.lex
--- a/acse/Acse.lex	Tue Feb 02 17:19:12 2010 +0100
+++ b/acse/Acse.lex	Thu Nov 29 11:08:52 2012 +0100
@@ -81,6 +81,8 @@
 ">"               { return GT; }
 "<<"              { return SHL_OP; }
 ">>"              { return SHR_OP; }
+"$<<$"            { return RSHL_OP; }
+"$>>$"            { return RSHR_OP; }
 "=="              { return EQ; }
 "!="              { return NOTEQ; }
 "<="              { return LTEQ; }
diff -r 4a0654b18dbe acse/Acse.y
--- a/acse/Acse.y	Tue Feb 02 17:19:12 2010 +0100
+++ b/acse/Acse.y	Thu Nov 29 11:08:52 2012 +0100
@@ -115,7 +115,7 @@
 %token LBRACE RBRACE LPAR RPAR LSQUARE RSQUARE
 %token SEMI COLON PLUS MINUS MUL_OP DIV_OP MOD_OP
 %token AND_OP OR_OP NOT_OP
-%token ASSIGN LT GT SHL_OP SHR_OP EQ NOTEQ LTEQ GTEQ
+%token ASSIGN LT GT SHL_OP SHR_OP RSHL_OP RSHR_OP EQ NOTEQ LTEQ GTEQ
 %token ANDAND OROR
 %token COMMA
 %token FOR
@@ -148,7 +148,7 @@
 %left AND_OP
 %left EQ NOTEQ
 %left LT GT LTEQ GTEQ
-%left SHL_OP SHR_OP
+%left SHL_OP SHR_OP RSHL_OP RSHR_OP
 %left MINUS PLUS
 %left MUL_OP DIV_OP
 %right NOT
@@ -548,6 +548,8 @@
    | exp SHR_OP exp  {  $$ = handle_bin_numeric_op(program, $1, $3, SHR); }
    | exp ANDAND exp  {  $$ = handle_bin_numeric_op(program, $1, $3, ANDL); }
    | exp OROR exp    {  $$ = handle_bin_numeric_op(program, $1, $3, ORL); }
+   | exp RSHL_OP exp {  $$ = handle_bin_numeric_op(program, $1, $3, RSHL); }
+   | exp RSHR_OP exp {  $$ = handle_bin_numeric_op(program, $1, $3, RSHR); }
    | LPAR exp RPAR   { $$ = $2; }
    | MINUS exp       {
                         if ($2.expression_type == IMMEDIATE)
diff -r 4a0654b18dbe acse/Makefile
--- a/acse/Makefile	Tue Feb 02 17:19:12 2010 +0100
+++ b/acse/Makefile	Thu Nov 29 11:08:52 2012 +0100
@@ -8,7 +8,7 @@
 all: $(project)
 
 $(project) : $(objects) $(cfiles) $(hfiles)
-	gcc -o $@ $(objects) $(cfiles)
+	gcc -O0 -g -o $@ $(objects) $(cfiles)
 
 Acse.tab.c : Acse.y
 	bison -d $<
diff -r 4a0654b18dbe acse/axe_constants.h
--- a/acse/axe_constants.h	Tue Feb 02 17:19:12 2010 +0100
+++ b/acse/axe_constants.h	Thu Nov 29 11:08:52 2012 +0100
@@ -80,6 +80,12 @@
 #define STORE 60
 #define AXE_READ 61
 #define AXE_WRITE 62
+
+/* Pseudo-opcode */
+#define RSHL 63
+#define RSHR 64
+
+/* Invalid opcode */
 #define INVALID_OPCODE -1
 
 /* data types */
diff -r 4a0654b18dbe acse/axe_expressions.c
--- a/acse/axe_expressions.c	Tue Feb 02 17:19:12 2010 +0100
+++ b/acse/axe_expressions.c	Thu Nov 29 11:08:52 2012 +0100
@@ -59,6 +59,10 @@
                              , exp1.value, exp2.value); break;
          case SHR : gen_shri_instruction (program, output_register
                              , exp1.value, exp2.value); break;
+         case RSHL : gen_rshli_emulation (program, output_register
+                              , exp1.value, exp2.value); break;
+         case RSHR : gen_rshri_emulation (program, output_register
+                              , exp1.value, exp2.value); break;
          case DIV :
                if (exp2.value == 0){
                   printWarningMessage(WARN_DIVISION_BY_ZERO);
@@ -132,6 +136,32 @@
                   gen_shr_instruction (program, output_register
                            , other_reg, exp2.value, CG_DIRECT_ALL);
                   break;
+         case RSHL :
+                  /* we have to load into a register the immediate value */
+                  other_reg = getNewRegister(program);
+
+                  /* In order to load the immediate inside a new
+                   * register we have to insert an ADDI instr. */
+                  gen_addi_instruction (program, output_register
+                            , REG_0, exp1.value);
+
+                  /* we have to emulate a RSHL instruction */
+                  gen_rshl_emulation (program, output_register
+                            , other_reg, exp2.value, CG_DIRECT_ALL);
+                  break;
+         case RSHR :
+                  /* we have to load into a register the immediate value */
+                  other_reg = getNewRegister(program);
+
+                  /* In order to load the immediate inside a new
+                   * register we have to insert an ADDI instr. */
+                  gen_addi_instruction (program, output_register
+                            , REG_0, exp1.value);
+
+                  /* we have to emulate a RSHR instruction */
+                  gen_rshr_emulation (program, output_register
+                            , other_reg, exp2.value, CG_DIRECT_ALL);
+                  break;
          default :
                   notifyError(AXE_INVALID_EXPRESSION);
       }
@@ -165,6 +195,12 @@
          case SHR :  gen_shl_instruction (program, output_register
                               , exp1.value, exp2.value, CG_DIRECT_ALL);
                      break;
+         case RSHL :  gen_rshl_emulation (program, output_register
+                               , exp1.value, exp2.value, CG_DIRECT_ALL);
+                      break;
+         case RSHR :  gen_rshr_emulation (program, output_register
+                               , exp1.value, exp2.value, CG_DIRECT_ALL);
+                      break;
          default :
                      notifyError(AXE_INVALID_EXPRESSION);
       }
@@ -186,6 +222,14 @@
       case MUL : return create_expression ((val1 * val2), IMMEDIATE);
       case SHL : return create_expression ((val1 << val2), IMMEDIATE);
       case SHR : return create_expression ((val1 >> val2), IMMEDIATE);
+      case RSHL: {
+         int res = (val1 >> (sizeof(int) * 8 - val2)) | (val1 << val2);
+         return create_expression (res, IMMEDIATE);
+      }
+      case RSHR: {
+         int res = (val1 << (sizeof(int) * 8 - val2)) | (val1 >> val2);
+         return create_expression (res, IMMEDIATE);
+      }
       case DIV :
          if (val2 == 0){
             printWarningMessage(WARN_DIVISION_BY_ZERO);
diff -r 4a0654b18dbe acse/axe_gencode.c
--- a/acse/axe_gencode.c	Tue Feb 02 17:19:12 2010 +0100
+++ b/acse/axe_gencode.c	Thu Nov 29 11:08:52 2012 +0100
@@ -674,3 +674,116 @@
    /* return the load instruction */
    return instr;
 }
+
+void gen_rshli_emulation
+      (t_program_infos *program, int r_dest, int r_source1, int immediate)
+{
+   gen_rshi_emulation(program, r_dest, r_source1, immediate, RSHL);
+}
+
+void gen_rshri_emulation
+      (t_program_infos *program, int r_dest, int r_source1, int immediate)
+{
+   gen_rshi_emulation(program, r_dest, r_source1, immediate, RSHR);
+}
+
+void gen_rshl_emulation (t_program_infos *program
+      , int r_dest, int r_source1, int r_source2, int flags)
+{
+   gen_rsh_emulation(program, r_dest, r_source1, r_source2, flags, RSHL);
+}
+
+void gen_rshr_emulation (t_program_infos *program
+      , int r_dest, int r_source1, int r_source2, int flags)
+{
+   gen_rsh_emulation(program, r_dest, r_source1, r_source2, flags, RSHR);
+}
+
+void gen_rshi_emulation (t_program_infos *program
+      , int r_dest, int r_source1, int immediate, int shift_op)
+{
+   int r_tmp1, r_tmp2;
+
+   /* The shift amount is constant, fold at compile-time. */
+   int discarded_shift = sizeof(int) * 8 - immediate;
+
+   /* Move discarded bits into the right place. */
+   r_tmp1 = getNewRegister(program);
+   switch(shift_op)
+   {
+      case RSHL:
+        gen_shri_instruction(program, r_tmp1, r_source1, discarded_shift);
+        break;
+      case RSHR:
+        gen_shli_instruction(program, r_tmp1, r_source1, discarded_shift);
+        break;
+      default:
+         notifyError(AXE_INVALID_INSTRUCTION);
+   }
+
+   /* Move not discarded bits into the right place. */
+   r_tmp2 = getNewRegister(program);
+   switch(shift_op)
+   {
+      case RSHL:
+        gen_shli_instruction(program, r_tmp2, r_source1, immediate);
+        break;
+      case RSHR:
+        gen_shri_instruction(program, r_tmp2, r_source1, immediate);
+        break;
+      default:
+         notifyError(AXE_INVALID_INSTRUCTION);
+   }
+
+   /* Combine the two values. */
+   gen_orb_instruction(program, r_dest, r_tmp1, r_tmp2, CG_DIRECT_ALL);
+}
+
+void gen_rsh_emulation (t_program_infos *program
+      , int r_dest, int r_source1, int r_source2, int flags, int shift_op)
+{
+   /* We support only direct addressing, for now. */
+   if(flags != CG_DIRECT_ALL)
+      notifyError(AXE_INVALID_INSTRUCTION);
+
+   int r_tmp1, r_tmp2, r_tmp3, r_tmp4;
+
+   /* The shift amount must be computed at run-time. */
+   r_tmp3 = getNewRegister(program);
+   r_tmp4 = getNewRegister(program);
+   gen_addi_instruction(program, r_tmp3, REG_0, sizeof(int) * 8);
+   gen_sub_instruction(program, r_tmp4, r_tmp3, r_source2, CG_DIRECT_ALL);
+
+   /* Move discarded bits into the right place. */
+   r_tmp1 = getNewRegister(program);
+   switch(shift_op)
+   {
+      case RSHL:
+        gen_shr_instruction(program, r_tmp1, r_source1, r_tmp4, CG_DIRECT_ALL);
+        break;
+      case RSHR:
+        gen_shl_instruction(program, r_tmp1, r_source1, r_tmp4, CG_DIRECT_ALL);
+        break;
+      default:
+         notifyError(AXE_INVALID_INSTRUCTION);
+   }
+
+   /* Move not discarded bits into the right place. */
+   r_tmp2 = getNewRegister(program);
+   switch(shift_op)
+   {
+      case RSHL:
+        gen_shl_instruction(program,
+                            r_tmp2, r_source1, r_source2, CG_DIRECT_ALL);
+        break;
+      case RSHR:
+        gen_shr_instruction(program,
+                            r_tmp2, r_source1, r_source2, CG_DIRECT_ALL);
+        break;
+      default:
+         notifyError(AXE_INVALID_INSTRUCTION);
+   }
+
+   /* Combine the two values. */
+   gen_orb_instruction(program, r_dest, r_tmp1, r_tmp2, CG_DIRECT_ALL);
+}
diff -r 4a0654b18dbe acse/axe_gencode.h
--- a/acse/axe_gencode.h	Tue Feb 02 17:19:12 2010 +0100
+++ b/acse/axe_gencode.h	Thu Nov 29 11:08:52 2012 +0100
@@ -495,5 +495,65 @@
 extern t_axe_instruction * gen_ble_instruction
       (t_program_infos *program, t_axe_label *label, int addr);
 
+/*----------------------------------------------------
+ *                   EMULATED INSTRUCTIONS
+ *---------------------------------------------------*/
+
+/* Used in order to create and assign to the current `program'
+ * a RSHLI instruction. An RTL representation for an RSHLI instruction
+ * of the form: RSHLI R1 R2 #IMM can be represented as follows:
+ * R1 <-- shift_left_rot(R2, IMM).
+ * `r_source1' and `immediate' are the two operands of the binary numeric
+ * operation. `r_dest' is a register location, `immediate' is an immediate
+ * value. 
+ *
+ * Since our machine does not have this kind of instruction, we emulate it. */
+extern void gen_rshli_emulation
+      (t_program_infos *program, int r_dest, int r_source1, int immediate);
+
+/* Used in order to create and assign to the current `program'
+ * a RSHRI instruction. An RTL representation for an RSHRI instruction
+ * of the form: RSHRI R1 R2 #IMM can be represented as follows:
+ * R1 <-- shift_right_rot(R2, IMM).
+ * `r_source1' and `immediate' are the two operands of the binary numeric
+ * operation. `r_dest' is a register location, `immediate' is an immediate
+ * value. 
+ *
+ * Since our machine does not have this kind of instruction, we emulate it. */
+extern void gen_rshri_emulation
+      (t_program_infos *program, int r_dest, int r_source1, int immediate);
+
+/* Used in order to create and assign to the current `program'
+ * a RSHL instruction. An RTL representation for an RSHL instruction
+ * of the form: RSHL R1 R2 R3 can be represented
+ * as follows: R1 <-- R2 shifted to left by R3 with rotation.
+ * `r_source1' and `r_source2' are the two operands of the binary numeric
+ * operation. `r_dest' is a register location. `r_dest' and `r_source2'
+ * are register locations that can be directly or indirectly addressed.
+ *
+ * Since our machine does not have this kind of instruction, we emulate it. */
+extern void gen_rshl_emulation (t_program_infos *program
+      , int r_dest, int r_source1, int r_source2, int flags);
+
+/* Used in order to create and assign to the current `program'
+ * a RSHR instruction. An RTL representation for an RSHR instruction
+ * of the form: RSHR R1 R2 R3 can be represented
+ * as follows: R1 <-- R2 shifted to right by R3 with rotation.
+ * `r_source1' and `r_source2' are the two operands of the binary numeric
+ * operation. `r_dest' is a register location. `r_dest' and `r_source2'
+ * are register locations that can be directly or indirectly addressed.
+ *
+ * Since our machine does not have this kind of instruction, we emulate it. */
+extern void gen_rshr_emulation (t_program_infos *program
+      , int r_dest, int r_source1, int r_source2, int flags);
+
+/* Generates the code for a generic shift-rotate emulation with immediate
+ * parameters. */
+extern void gen_rshi_emulation (t_program_infos *program
+      , int r_dest, int r_source1, int immediate, int shift_op);
+
+/* Generates the code for a generic shift-rotate emulation. */
+extern void gen_rsh_emulation (t_program_infos *program
+      , int r_dest, int r_source1, int r_source2, int flags, int shift_op);
 
 #endif
diff -r 4a0654b18dbe tests/Makefile
--- a/tests/Makefile	Tue Feb 02 17:19:12 2010 +0100
+++ b/tests/Makefile	Thu Nov 29 11:08:52 2012 +0100
@@ -1,7 +1,8 @@
 asm=$(CURDIR)/../bin/asm
 acse=$(CURDIR)/../bin/acse
 export asm acse
-dirs:=arrays sum dowhile fact mult_table power semi assign arrays arrays2 misc
+dirs:=arrays sum dowhile fact mult_table power semi assign arrays arrays2 misc \
+      shift-rotate
 
 test :
 	for i in $(dirs); do $(MAKE) -C $$i -f ../Makefile.test ; done
diff -r 4a0654b18dbe tests/shift-rotate/left-shift.src
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/shift-rotate/left-shift.src	Thu Nov 29 11:08:52 2012 +0100
@@ -0,0 +1,12 @@
+
+int a, b, c, d;
+
+/* To see the cyclic behaviour, sizeof(int) must be 32 on your system */
+a = 1 << 31;
+b = 1 $<<$ 0;
+c = a $<<$ 1;
+d = a $<<$ b;
+write(a);
+write(b);
+write(c);
+write(d);
diff -r 4a0654b18dbe tests/shift-rotate/right-shift.src
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/shift-rotate/right-shift.src	Thu Nov 29 11:08:52 2012 +0100
@@ -0,0 +1,11 @@
+
+int a, b, c, d;
+
+a = 1;
+b = 1 $>>$ 0;
+c = a $>>$ 1;
+d = a $>>$ b;
+write(a);
+write(b);
+write(c);
+write(d);
