View Javadoc

1   package com.tapina.robe.swi.clib;
2   
3   import com.tapina.robe.runtime.*;
4   import com.tapina.robe.runtime.instruction.DataProcessingInstruction;
5   import com.tapina.robe.runtime.instruction.RegisterOperand;
6   
7   import java.util.logging.Logger;
8   
9   /***
10   * This class represents a SharedCLibrary routine as a code block.
11   * The code block has a set addres but does not have a physical length and the native ARM instructions do not exist.
12   */
13  public abstract class Stub extends CodeBlock {
14      public static final int A1 = 0, A2 = 1, A3 = 2, A4 = 3;
15      public static final int V1 = 4, V2 = 5, V3 = 6, V4 = 7, V5 = 8, V6 = 9;
16      public static final int SL = 10, FP = 11, IP = 12, SP = 13, LR = 14, PC = 15;
17      
18      protected final Logger log = Logger.getLogger(getClass().getName());
19  
20      public Stub() {
21          super(0); // Address will be set later
22      }
23  
24      public void execute(Environment environment) {
25          executeStub(environment);
26          unwind(environment);
27      }
28  
29      void unwind(Environment environment) {
30          UNWIND_INSTRUCTION.checkAndExecute(environment);
31      }
32  
33      public abstract void executeStub(Environment environment);
34  
35      public void setAddress(int address) {
36          super.setAddress(address);
37      }
38  
39      private final static Instruction UNWIND_INSTRUCTION = 
40              new DataProcessingInstruction(Condition.AL, DataProcessingInstruction.MOV, 15, 0, 
41                      new RegisterOperand(14), true, true);
42  
43      protected void executeSubroutine(Environment environment, CodeBlock codeBlock) {
44          final CPU cpu = environment.getCpu();
45          final int[] R = cpu.R;
46          final int routineAddress = codeBlock.getAddress();
47          final int R14save = R[14];
48          R[14] = this.getAddress() + 4;
49          R[15] = routineAddress + 8; // Make sure PC is set correctly
50          while (true) {
51              try {
52                  codeBlock.execute(environment);
53              } catch (DecoderException e) {
54                  throw new RuntimeException(e);
55              }
56              if (cpu.getPC() == this.getAddress() + 4) {
57                  // The initialisation routine ended
58                  break;
59              }
60              // Otherwise it issued its own branch instruction
61              final int pc = cpu.getPC();
62              codeBlock = environment.getMemoryMap().addEntryPoint(pc);
63              R[15] += 8;
64          }
65          R[14] = R14save;
66      }
67  }