Improve thumb compiler

* `ldr rn, #` requires an input to be a multiple of 4
* `ldrh rn, #` requires an input to be a multiple of 2
* `ldrb rn, #` requires an input to be a multiple of 1
* `add sp, #` and `sub sp, #` require the input to be a multiple of 4
* `add rd, sp, #` and `add rd, pc, #` require the input to be a multiple of 4
This commit is contained in:
Benjamin Popp 2020-10-07 09:03:01 -05:00
parent 3a87de086f
commit ea22201fe9
8 changed files with 29 additions and 19 deletions

View File

@ -420,6 +420,10 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
} else if (part.Type == InstructionArgType.Numeric) {
if (part.Code != 0) {
instruction = CalculatePcRelativeAddress(instruction, pcAddress, part, bits);
} else if (instruction.Contains("#=#*")) {
var multiplierIndex = instruction.IndexOf("#=#*") + 4;
var multiplier = instruction[multiplierIndex] - '0';
instruction = instruction.Replace("#=#*" + instruction[multiplierIndex], $"#{bits * multiplier}");
} else {
instruction = instruction.Replace("#", $"#{bits}");
}
@ -584,6 +588,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
// read a register
if (template[0] == 'r') {
if (line.StartsWith("sp")) line = "r13" + line.Substring(2);
if (line.StartsWith("lr")) line = "r14" + line.Substring(2);
if (line.StartsWith("pc")) line = "r15" + line.Substring(2);
if (line[0] != 'r') return false;
@ -627,6 +632,11 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
}
template = template.Substring(1);
line = line.Substring(numberAsText.Length + 1);
if (template.StartsWith("=#*")) {
var multiplier = template[3] - '0';
template = template.Substring(4);
numeric /= multiplier;
}
continue;
}

View File

@ -70,16 +70,16 @@ nv=1111 @ never
01100 # rn rd | str rd, [rn, #]
01101 # rn rd | ldr rd, [rn, #]
0110100000 rn rd | ldr rd, [rn]
01110 # rn rd | strb rd, [rn, #] @ #=#*4]
01111 # rn rd | ldrb rd, [rn, #] @ #=#*4]
10000 # rn rd | strh rd, [rn, #] @ #=#*4]
10001 # rn rd | ldrh rd, [rn, #] @ #=#*4]
10010 rd # | str rd, [sp, #] @ #=#*4]
10011 rd # | ldr rd, [sp, #] @ #=#*4]
10100 rd # | add rd, pc, # @ =#*4 @ rd = pc + #*4
10101 rd # | add rd, sp, # @ =#*4 @ rd = sp + #*4
101100000 # | add sp, # @ =#*4 @ sp += #*4
101100001 # | sub sp, # @ =#*4 @ sp -= #*4
01110 # rn rd | strb rd, [rn, #]
01111 # rn rd | ldrb rd, [rn, #]
10000 # rn rd | strh rd, [rn, #=#*2]
10001 # rn rd | ldrh rd, [rn, #=#*2]
10010 rd # | str rd, [sp, #=#*4]
10011 rd # | ldr rd, [sp, #=#*4]
10100 rd # | add rd, pc, #=#*4 @ rd = pc + #*4
10101 rd # | add rd, sp, #=#*4 @ rd = sp + #*4
101100000 # | add sp, #=#*4 @ sp += #*4
101100001 # | sub sp, #=#*4 @ sp -= #*4
10110100 list | push {list}
10110101 list | push lr, {list} @ note: 'tsil' is a reverse 'list'. The bits are stored in the opposite order.
10111100 list | pop {list}

View File

@ -86,7 +86,7 @@ namespace HavenSoft.HexManiac.Tests {
Assert.Equal(5, parts.Length);
}
// [Theory]
[Theory]
[InlineData("Expand01_-_Move_Stats")]
[InlineData("Expand02_-_Pokemon_Move_Learn_Table")]
[InlineData("Expand03_-_Relearner_move_tutor")]

View File

@ -8,7 +8,6 @@ using HavenSoft.HexManiac.Core.ViewModels.Tools;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using Xunit;
@ -399,7 +398,8 @@ namespace HavenSoft.HexManiac.Tests {
[InlineData("bx lr", 0b010001110_1_110_000)]
[InlineData("ldr r1, [r2]", 0b01101_00000_010_001)]
[InlineData("lsl r1, r2, #0x4", 0b00000_00100_010_001)]
// [InlineData("sub sp, #4", 0b101100001_0000001)]
[InlineData("sub sp, #4", 0b101100001_0000001)]
[InlineData("mov r3, sp", 0x46_6B)]
public void ThumbCompilerTests(string input, uint output) {
var bytes = new List<byte> { (byte)output, (byte)(output >> 8) };
var model = new PokemonModel(new byte[0x200]);

View File

@ -112,13 +112,13 @@
<None Include="app.config" />
<None Include="packages.config" />
<None Include="test_compiled\Expand01_-_Move_Stats.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="test_compiled\Expand02_-_Pokemon_Move_Learn_Table.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="test_compiled\Expand03_-_Relearner_move_tutor.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
@ -133,13 +133,13 @@
<ItemGroup />
<ItemGroup>
<Content Include="test_code\Expand01_-_Move_Stats.asm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="test_code\Expand02_-_Pokemon_Move_Learn_Table.asm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="test_code\Expand03_-_Relearner_move_tutor.asm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />