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);
20
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");
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 }