summaryrefslogtreecommitdiff
path: root/log.md
blob: c96d8e59c942cb50f0fdc7dfa32985a6c6a0a870 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# Bachelor thesis logbook

Camil Staps

### 2016-09-18
Made a Vim plugin for ABC code highlighting (camilstaps/vim-abc).

ARM/Thumb-2 mode switches are expensive, and since a Clean program continuously
switches between the RTS and the program itself, it is not viable to have the
RTS run in ARM mode and the code generator generate Thumb-2 code. Hence, I
started to rewrite the RTS for Thumb-2. Mostly minor, trivial changes:

 - Invisible registers for some instructions (auxiliary register needed)

Started to make changes to the code generator:

 - Added `.thumb`, `.syntax unified` to the top of each generated file
 - Added `.thumb_func` before each code label
 - Fix for the `str pc,[sp,#-4]!` and similar instructions, since `pc` cannot
   be the `Rd` operand in a `str` instruction: copy to scratch register first.

**Question**:
Is there an interface to get an auxiliary register in the code generator? For
example, to swap to registers a third is necessary (or the stack, but then the
PC and SP cannot be modified). In `w_as_jsr_instruction`, the PC is stored on
the stack, but PC cannot be `Rd` for `str`. Therefore we need an auxiliary
register (`8c91384` does this for some cases). *Answer on 09-19*.

### 2016-09-19
Talked to John:

 - (*Answer to question from 09-18*) Registers R14 (LR) and probably also R12
   are scratch registers and can be used at any time.
 - When the program counter is stored on the stack in ARM (`str pc,[sp,#-4]!`),
   the value pushed is actually the PC + 8, which gives space for a call after
   storing the PC. On Thumb-2 this is different, so this should be checked.

To solve the latter problem, we need to add an offset to the stored PC. Old ARM
code was:

```armasm
str pc,[sp,#-4]!   @ Actually pushed PC+8, to after the branch.
```

First solution, since `PC` cannot be `Rd` for `str`:

```armasm
mov r12,pc         @ Stores PC+4 (see A5.1.2 of the ARMv7-A manual) (this is a 16-bit instruction)
str r12,[sp,#-4]!  @ Pushes stored value (address of THIS register)
```

New solution, with a proper offset:

```armasm
add r12,pc,#9      @ Stores PC+12+1 (this is a 32-bit instruction)
                   @ +1; bit 0 is the execution state and should be Thumb-2
str r12,[sp,#-4]!  @ This is a 32-bit instruction, as is the branch below
```

After this, this program crashes only when it wants to print time information
(specifically, `time_string_4`, `thumb2startup.s:929`):

```clean
Start = 10
```

The last crash has to do with alignment in `exit_clean` (`thumb2startup.s`).
This indicates that `add r12,pc,#9` is not right in some cases. The second
bullet point in A5.1.2 applies:

> Read the word-aligned PC value, that is, the address of the current
> instruction + 4, with bits [1:0] forced to zero.

Hence, in some cases (when the address of the `add` instruction is 2 mod 4), we
should add 11 instead of 9. A quick fix is to use `.align`, which inserts a
`nop` if needed. It would be more convenient if there would be preprocessor
directives like `.align` where you could yourself decide what is added
depending on the current alignment (see
http://stackoverflow.com/q/39582517/1544337 for this).