View Javadoc

1   package com.tapina.robe.runtime.instruction;
2   
3   import com.tapina.robe.runtime.Environment;
4   import com.tapina.robe.runtime.Instruction;
5   import com.tapina.robe.runtime.Condition;
6   
7   import java.io.Writer;
8   import java.io.IOException;
9   
10  /***
11   * Created by IntelliJ IDEA.
12   * User: gareth
13   * Date: Sep 2, 2003
14   * Time: 9:15:17 AM
15   */
16  public final class DataTransferInstruction extends Instruction {
17      public final static Transfer LDR = new Transfer() {
18          public void transfer(Environment env, int destinationRegister, int address) {
19              int word = env.getMemoryMap().getWord(address & ~3); // THIS LINE IS CAUSING TROUBLE
20              // Corrective action for misalignment
21              if ((address & 3) != 0) {
22                  final int shift = (address & 3) * 8;
23                  word = (word >>> shift) | (word << (32 - shift));
24              }
25              if (destinationRegister != 15) {
26                  env.getCpu().R[destinationRegister] = word;
27              } else {
28                  env.getCpu().setPC(word);
29              }
30          }
31  
32          public void dumpJavaSource(int destinationRegister, Writer out) throws IOException {
33              out.write("{\n");
34              out.write("int word = memoryMap.loadWord(address & ~3);\n");
35              out.write("if ((address & 3) != 0) {\n");
36              out.write("final int shift = (address & 3) * 8;\n");
37              out.write("word = (word >>> shift) | (word << (32 - shift));\n");
38              out.write("}\n");
39              if (destinationRegister != 15) {
40                  out.write("R[" + destinationRegister + "] = word;\n");
41              } else {
42                  out.write("cpu.setPC(word);\n");
43              }
44          }
45      };
46      public final static Transfer LDRB = new Transfer() {
47          public void transfer(Environment env, int destinationRegister, int address) {
48              env.getCpu().R[destinationRegister] = ((int) env.getMemoryMap().getByte(address)) & 0xff;
49          }
50  
51          public void dumpJavaSource(int destinationRegister, Writer out) throws IOException {
52              out.write("R[" + destinationRegister + "] = ((int) memoryMap.loadByte(address)) & 0xff;\n");
53          }
54      };
55      public final static Transfer STR = new Transfer() {
56          public void transfer(Environment env, int destinationRegister, int address) {
57              if ((address & 3) != 0) {
58                  log.info("STR to unaligned address: aligning"); // think this is correct
59              }
60              env.getMemoryMap().storeWord(address & ~3, env.getCpu().R[destinationRegister]);
61          }
62  
63          public void dumpJavaSource(int destinationRegister, Writer out) throws IOException {
64              out.write("memoryMap.storeWord(adress & ~3, R[" + destinationRegister + "];\n");
65          }
66      };
67      public final static Transfer STRB = new Transfer() {
68          public void transfer(Environment env, int destinationRegister, int address) {
69              env.getMemoryMap().storeByte(address, (byte) (env.getCpu().R[destinationRegister] & 0xff));
70          }
71  
72          public void dumpJavaSource(int destinationRegister, Writer out) throws IOException {
73              out.write("memoryMap.storeByte(address, (byte) R[" + destinationRegister + "] & 0xff);\n");
74          }
75      };
76  
77      private final Transfer transfer;
78      private final int Rd;
79      private final IndexedAddressSource addressSource;
80  
81      public DataTransferInstruction(Condition condition, Transfer transfer, int destinationRegister,
82                                     IndexedAddressSource addressSource) {
83          super(condition);
84          this.transfer = transfer;
85          this.Rd = destinationRegister;
86          this.addressSource = addressSource;
87      }
88  
89      protected final boolean execute(Environment environment) {
90          transfer.transfer(environment, Rd, addressSource.getTransferAddress(environment.getCpu()));
91          return (transfer == LDR || transfer == LDRB) && Rd == 15;
92      }
93  
94      public void dumpJavaSourceUnconditional(Writer out) throws IOException {
95          addressSource.dumpJavaSource("address", out);
96          transfer.dumpJavaSource(Rd, out);
97          if ((transfer == LDR || transfer == LDRB) && Rd == 15) {
98              out.write("return;\n");
99          }
100     }
101 }