1 package com.tapina.robe.runtime.instruction;
2
3 import com.tapina.robe.runtime.CPU;
4
5 import java.io.Writer;
6 import java.io.IOException;
7
8 /***
9 * Created by IntelliJ IDEA.
10 * User: gareth
11 * Date: Aug 23, 2003
12 * Time: 10:54:20 PM
13 */
14 public final class RegisterOperand extends Operand {
15 public static final int SHIFT_LOGICAL_LEFT = 0;
16 public static final int SHIFT_LOGICAL_RIGHT = 1;
17 public static final int SHIFT_ARITHMETIC_RIGHT = 2;
18 public static final int SHIFT_ROTATE_RIGHT = 3;
19
20 private final int registerNumber;
21 private final int shiftType;
22 private final Operand shiftValue;
23 private boolean shiftPerformed = false;
24 private boolean carryFlag = false;
25
26 public RegisterOperand(int registerNumber) {
27 this(registerNumber, 0, new ImmediateOperand(0));
28 }
29
30 public RegisterOperand(int registerNumber, int shiftType, Operand shiftValue) {
31 this.registerNumber = registerNumber;
32 this.shiftType = shiftType;
33 this.shiftValue = shiftValue;
34 }
35
36 public final int getValue(CPU cpu) {
37 int[] R = cpu.R;
38
39
40 int value = R[registerNumber];
41 int shift = shiftValue.getValue(cpu) & 0xff;
42
43 if (!(shiftType == SHIFT_LOGICAL_LEFT && shift == 0)) {
44
45 shiftPerformed = true;
46 int carry = 0;
47 switch (shiftType) {
48
49 case SHIFT_LOGICAL_LEFT:
50
51 carry = value & (1 << (32 - shift));
52 value <<= shift;
53 break;
54 case SHIFT_LOGICAL_RIGHT:
55 if (shift == 0) {
56 shift = 32;
57 }
58 carry = value & (1 << (shift - 1));
59 value >>>= shift;
60 break;
61 case SHIFT_ARITHMETIC_RIGHT:
62 if (shift == 0) {
63 shift = 32;
64 }
65
66 carry = value & (1 << (shift - 1));
67 value >>= shift;
68 break;
69 case SHIFT_ROTATE_RIGHT:
70 carry = value & (1 << (shift));
71 if (shift != 0) {
72 value = (value >>> shift) | (value << (32-shift));
73 } else {
74 value = (value >>> 1);
75 }
76 }
77 carryFlag = (carry != 0);
78 }
79
80 return value;
81 }
82
83 public void dumpJavaSource(String varName, Writer out) throws IOException {
84 out.write("final boolean " + varName + ";\n");
85 out.write("final boolean shiftPerformed;\n");
86 out.write("final boolean carryFlag;\n");
87 out.write("{\n");
88 out.write("final int carry;\n");
89 out.write("int value = R[" + registerNumber + "];\n");
90 shiftValue.dumpJavaSource("shift", out);
91 out.write("shiftValue &= 0xff;\n");
92 switch (shiftType) {
93 case SHIFT_LOGICAL_LEFT:
94 out.write("if (shift != 0) {\n");
95 out.write("carry = value & (1 << (32 - shift));\n");
96 out.write("value <<= shift;\n");
97 out.write("}\n");
98 break;
99 case SHIFT_LOGICAL_RIGHT:
100 out.write("if (shift == 0) { shift = 32; }\n");
101 out.write("carry = value & (1 << (shift - 1));\n");
102 out.write("value >>>= shift;\n");
103 break;
104 case SHIFT_ARITHMETIC_RIGHT:
105 out.write("if (shift == 0) { shift = 32; }\n");
106 out.write("carry = value & (1 << (shift - 1));\n");
107 out.write("value >>= shift;\n");
108 break;
109 case SHIFT_ROTATE_RIGHT:
110 out.write("carry = value & (1 << shift);\n");
111 out.write("if (shift != 0) {\n");
112 out.write("value = (value >>> shift) | (value << (32 - shift));\n");
113 out.write("} else {\n");
114 out.write("value = (value >>> 1)\n");
115 out.write("}\n");
116 }
117 out.write(varName + " = value;\n");
118 out.write("carryFlag = (carry != 0);\n");
119 if (shiftType == SHIFT_LOGICAL_LEFT) {
120 out.write("shiftPerformed = (shift != 0);\n");
121 } else {
122 out.write("shiftPerformed = true;\n");
123 }
124 out.write("}\n");
125 }
126
127 public String getJavaExpression() {
128 return null;
129 }
130
131 public final boolean isShiftPerformed() {
132 return shiftPerformed;
133 }
134
135 public final boolean isCarryFlagSet() {
136 return carryFlag;
137 }
138 }