ARC_Simulator.doArithmetic()

Additions are highlighted.



  //  doArithmetic()
  //  ----------------------------------------------------------------
  /**
   *    Process arithmetic instructions.
   *
   *    @throws UnimplementedOpcodeException if the op3 field is not
   *            recognized.
   */
    static void doArithmetic()     throws UnimplementedOpcodeException
    {
      switch ( IR.op3 )
      {
        case 000: //  add - Extended opcode
          lognl( "  add" );
          Registers.setValue( IR.rd, ALU.do_op( 
                       Registers.getValue( IR.rs1 ), (IR.i_bit == 1) ?
                    IR.simm13 : Registers.getValue( IR.rs2 ), ADD ) );
          break;

        case 004: //  sub - Extended opcode
          lognl( "  sub" );
          //  Get second operand
          if ( IR.i_bit == 1 )
          {
            Registers.setValue( t0, IR.simm13 );
          }
          else
          {
            Registers.setValue( t0, Registers.getValue( IR.rs2) );
          }
          //  Negate second operand and add
          Registers.setValue( t0, ALU.do_op( Registers.getValue( t0 ),
                                     Registers.getValue( r0 ), NOR ));
          Registers.setValue( t0, ALU.do_op( Registers.getValue( t0 ),
                                     Registers.getValue( r0 ), INC ));
          Registers.setValue( IR.rd,
                              ALU.do_op( Registers.getValue( IR.rs1 ),
                                     Registers.getValue( t0 ), ADD ));
          break;

        case 020: //  addcc
          lognl( "  addcc" );
          Registers.setValue( IR.rd, ALU.do_op( 
                       Registers.getValue( IR.rs1 ), (IR.i_bit == 1) ?
                  IR.simm13 : Registers.getValue( IR.rs2 ), ADDCC ) );
          break;

        case 021: //  andcc
          lognl( "  andcc" );
          Registers.setValue( IR.rd, ALU.do_op( 
                       Registers.getValue( IR.rs1 ), (IR.i_bit == 1) ?
                  IR.simm13 : Registers.getValue( IR.rs2 ), ANDCC ) );
          break;

        case 022: //  orcc
          lognl( "  orcc" );
          Registers.setValue( IR.rd, ALU.do_op( 
                       Registers.getValue( IR.rs1 ), (IR.i_bit == 1) ?
                   IR.simm13 : Registers.getValue( IR.rs2 ), ORCC ) );
          break;

        case 024: //  subcc - Extended opcode
          lognl( "  subcc" );
          //  Get second operand
          if ( IR.i_bit == 1 )
          {
            Registers.setValue( t0, IR.simm13 );
          }
          else
          {
            Registers.setValue( t0, Registers.getValue( IR.rs2) );
          }
          //  Negate second operand and add
          Registers.setValue( t0, ALU.do_op( Registers.getValue( t0 ),
                                     Registers.getValue( r0 ), NOR ));
          Registers.setValue( t0, ALU.do_op( Registers.getValue( t0 ),
                                     Registers.getValue( r0 ), INC ));
          Registers.setValue( IR.rd,
                              ALU.do_op( Registers.getValue( IR.rs1 ),
                                   Registers.getValue( t0 ), ADDCC ));
          break;
        case 026: //  orncc
          lognl( "  orncc" );
          Registers.setValue( IR.rd, ALU.do_op( 
                       Registers.getValue( IR.rs1 ), (IR.i_bit == 1) ?
                  IR.simm13 : Registers.getValue( IR.rs2 ), NORCC ) );
          break;

        case 046: //  srl
          lognl( "  srl" );
          Registers.setValue( IR.rd, ALU.do_op( 
                       Registers.getValue( IR.rs1 ), (IR.i_bit == 1) ?
                    IR.simm13 : Registers.getValue( IR.rs2 ), SRL ) );
          break;

        case 070: //  jmpl
          lognl( "  jmpl" );
          Registers.setValue( IR.rd, Registers.getValue( pc ) );
          Registers.setValue( IR.pc, 
            ALU.do_op( Registers.getValue( IR.rs1 ), (IR.i_bit == 1) ?
                    IR.simm13 : Registers.getValue( IR.rs2 ), ADD ) );
          return;  // Don't update PC

        default:
          throw new UnimplementedOpcodeException( 
           "  Unimplemented Arithmetic op3: " + oxydize( IR.op3, 3) );
      }
      //  All arithmetic instructions except jmpl update the pc.
      Registers.setValue( pc, 
             ALU.do_op( Registers.getValue(pc), 0, INCPC ));
    }


  //  doMemory()
  //  ----------------------------------------------------------------
  /**
   *    Process ld/st instructions.
   * 
   *    @throws UnimplementedOpcodeException if the op3 field is not
   *            recognized.
   */
    static void doMemory()         throws UnimplementedOpcodeException
    {
      switch ( IR.op3 )
      {
        case 000:
          lognl( "  ld" );
          Registers.setValue( t0,
                              ALU.do_op( Registers.getValue( IR.rs1 ),
           (IR.i_bit == 1) ? IR.simm13 : Registers.getValue( IR.rs2 ),
                                                               ADD ));
          Registers.setValue( IR.rd,
                        Memory.readWord( Registers.getValue( t0 ) ) );
          break;

        case 004:
          lognl( "  st" );
          Registers.setValue( t0,
                              ALU.do_op( Registers.getValue( IR.rs1 ),
           (IR.i_bit == 1) ? IR.simm13 : Registers.getValue( IR.rs2 ),
                                                               ADD ));
          Memory.writeWord( Registers.getValue( t0 ), 
                            Registers.getValue( IR.rd ));
          break;

        default:
          throw new UnimplementedOpcodeException( 
                "  Unimplemented Memory op3: " + oxydize(IR.op3, 3) );
      }

      //  Both memory operations update the pc.
      Registers.setValue( pc, 
             ALU.do_op( Registers.getValue(pc), 0, INCPC ));
    }
  }