From 6aec0ce695cd3609544365b7cc0d75a7a99cd7a3 Mon Sep 17 00:00:00 2001 From: David Given Date: Thu, 30 May 2024 23:34:20 +0200 Subject: [PATCH] Archival checkin of the non-functional cowasm2 variable-sized-instruction stuff. --- src/cowasm2/arch68000.coh | 3 +- src/cowasm2/arch68000.y | 120 ++++++++++++++++++++++++------------- src/cowasm2/archac1082.cow | 1 + src/cowasm2/build.lua | 1 + src/cowasm2/cowasm2.coh | 2 + src/cowasm2/sizing.coh | 37 ++++++++++++ src/cowasm2/types.coh | 2 +- 7 files changed, 122 insertions(+), 44 deletions(-) create mode 100644 src/cowasm2/sizing.coh diff --git a/src/cowasm2/arch68000.coh b/src/cowasm2/arch68000.coh index 1d6fe13d..fc23a275 100644 --- a/src/cowasm2/arch68000.coh +++ b/src/cowasm2/arch68000.coh @@ -65,7 +65,7 @@ sub IsLvalueD(am: uint8): (r: uint8) is if am == AM_REGA then r := 0; else - am := IsLvalue(am); + r := IsLvalue(am); end if; end sub; @@ -307,6 +307,7 @@ include "lexer.coh"; include "utils.coh"; include "emitter.coh"; include "symbols.coh"; +include "sizing.coh"; sub DisplacementOutOfRange(disp: uint32, max: uint32) is if disp > max then diff --git a/src/cowasm2/arch68000.y b/src/cowasm2/arch68000.y index f4560991..bac2faa1 100644 --- a/src/cowasm2/arch68000.y +++ b/src/cowasm2/arch68000.y @@ -374,43 +374,65 @@ instruction ::= INSN_ASL(T) mod(M) ea(R1). instruction ::= INSN_BRA(T) mod expression(E). { + var sizeByte := GetNextSizeRecord(); if pass == 1 then - [currentProgramCounter] := [currentProgramCounter] + 6; + [sizeByte] := 10; + [currentProgramCounter] := [currentProgramCounter] + 10; + #elseif E.type == AS_NUMBER then + # case T.number as uint8 is + # when 0: # bra + # [sizeByte] := 6; + # Emit16(0b0100111011111001); # jmp + + # when 1: # bsr + # [sizeByte] := 6; + # Emit16(0b0100111010111001); # jsr + + # when else: # long conditional + # [sizeByte] := 8; + # Emit16(((T.number as uint16 ^ 1) << 8) + # | 0b0110000000000110); + # Emit16(0b0100111010111001); # jmp + # end case; + # Emit32(&E); else - var delta: int32; - if E.type == AS_NUMBER then - case T.number as uint8 is - when 0: # bra - Emit16(0b0100111011111001); - - when 1: # jsr - Emit16(0b0100111010111001); - - when else: # long conditional - Emit16(((T.number as uint16 ^ 1) << 8) - | 0b0110000000000110); - Emit16(0b0100111010111001); # jmp - end case; - Emit32(&E); - return; - elseif E.type == currentSegment then - delta := (E.number - [currentProgramCounter] - 2) as int32; - if (delta >= -0x80) and (delta <= 0x7f) then + var delta := (E.number - [currentProgramCounter] - 2) as int32; + + var size: uint8; + if (delta >= -0x80) and (delta <= 0x7f) then + size := 2; + elseif (delta >= -0x8000) and (delta <= 0x7fff) then + size := 4; + else + size := 10; + end if; + print_hex_i32(sizeByte as intptr as uint32); + print(" "); + print_hex_i32(delta as uint32); + print("\n"); + if size > [sizeByte] then + SizeInvariantError(); + end if; + [sizeByte] := size; + + case size is + when 2: Emit16((T.number as uint16 << 8) | 0b0110000000000000 | (delta as uint8 as uint16)); - elseif (delta >= -0x8000) and (delta <= 0x7fff) then + + when 4: Emit16((T.number as uint16 << 8) | 0b0110000000000000); Emit16(delta as uint16); - else + + when 10: Emit16(((T.number as uint16 ^ 1) << 8) | 0b0110000000000110); Emit16(6); Emit16(0b0100111010111001); Emit32(&E); - end if; - end if; + end case; end if; } @@ -422,30 +444,44 @@ instruction ::= INSN_DBT(T) ea(R) COMMA expression(E). InvalidOperand(); end if; + if E.type == AS_NUMBER then + Emit16((T.number as uint16 ^ 0x100) + | (R.reg as uint16)); + Emit16(0b0100111010111001); # jmp + Emit32(&E); + return; + end if; + + var s: uint8[1]; + var sizeByte := &s[0]; + #var sizeByte := GetNextSizeRecord(); + var delta := (E.number - [currentProgramCounter] - 2) as int32; if pass == 1 then + [sizeByte] := 10; [currentProgramCounter] := [currentProgramCounter] + 10; else - var delta: int32; - if E.type == AS_NUMBER then + var size: uint8; + + if (delta >= -0x8000) and (delta <= 0x7fff) then + size := 4; + else + size := 10; + end if; + if size > [sizeByte] then + SizeInvariantError(); + end if; + [sizeByte] := size; + + if size == 4 then + Emit16((T.number as uint16) + | (R.reg as uint16)); + Emit16(delta as uint16); + else Emit16((T.number as uint16 ^ 0x100) | (R.reg as uint16)); + Emit16(6); Emit16(0b0100111010111001); # jmp Emit32(&E); - return; - elseif E.type == currentSegment then - delta := (E.number - [currentProgramCounter] - 2) as int32; - if (delta >= -0x8000) and (delta <= 0x7fff) then - Emit16((T.number as uint16) - | (R.reg as uint16)); - Emit16(delta as uint16); - else - Emit16((T.number as uint16 ^ 0x100) - | (R.reg as uint16)); - Emit16(6); - Emit16(0b0100111010111001); # jmp - Emit32(&E); - end if; - return; end if; end if; } @@ -496,7 +532,7 @@ instruction ::= INSN_BTST(T) ea(R1) COMMA ea(R2). instruction ::= INSN_CHK(T) mod(M) ea(R1) COMMA ea(R2). { - if (IsLvalueD(R1.mode) == 0) or (R2.mode != AM_REGD) or (M != 1) then + if (IsRvalueD(R1.mode) == 0) or (R2.mode != AM_REGD) or (M != 1) then InvalidOperand(); end if; diff --git a/src/cowasm2/archac1082.cow b/src/cowasm2/archac1082.cow index 12cd4775..2394ba86 100644 --- a/src/cowasm2/archac1082.cow +++ b/src/cowasm2/archac1082.cow @@ -153,6 +153,7 @@ include "lexer.coh"; include "utils.coh"; include "emitter.coh"; include "symbols.coh"; +include "sizing.coh"; sub Emit16(w: uint16) is Emit8((w >> 8) as uint8); diff --git a/src/cowasm2/build.lua b/src/cowasm2/build.lua index fdf7a3ba..b0ba49e2 100644 --- a/src/cowasm2/build.lua +++ b/src/cowasm2/build.lua @@ -35,6 +35,7 @@ local function build(arch, yarch) "src/cowasm2/lexer.coh", "src/cowasm2/symbols.coh", "src/cowasm2/types.coh", + "src/cowasm2/sizing.coh", "$OBJ/src/cowasm2/arch"..yarch..".parser.coh", "$OBJ/src/cowasm2/arch"..yarch..".tokens.coh", }, deps), diff --git a/src/cowasm2/cowasm2.coh b/src/cowasm2/cowasm2.coh index 258e47c0..6bdc1c4f 100644 --- a/src/cowasm2/cowasm2.coh +++ b/src/cowasm2/cowasm2.coh @@ -63,7 +63,9 @@ sub Parse() is print_i8(pass); print_nl(); + lineno := 1; UpdateProgramCounters(); + RewindSizePointer(); CheckFCBOpen(FCBOpenIn(&inputFile, inputFilename), inputFilename); ParserInit(); diff --git a/src/cowasm2/sizing.coh b/src/cowasm2/sizing.coh new file mode 100644 index 00000000..ec95edb7 --- /dev/null +++ b/src/cowasm2/sizing.coh @@ -0,0 +1,37 @@ +record SizeRecord is + array: uint8[256]; + next: [SizeRecord]; +end record; + +var firstSizeRecord_s: SizeRecord; +var firstSizeRecord := &firstSizeRecord_s; +var currentSizeRecord: [SizeRecord]; +var currentOffset: uint8; + +sub RewindSizePointer() is + currentSizeRecord := firstSizeRecord; + currentOffset := 0; +end sub; + +sub GetNextSizeRecord(): (result: [uint8]) is + result := ¤tSizeRecord.array[currentOffset]; + + print_hex_i32(result as intptr as uint32); + print(" "); + print_hex_i8([result]); + print_nl(); + currentOffset := currentOffset + 1; + if currentOffset == 0 then + var next := currentSizeRecord.next; + if next == (0 as [SizeRecord]) then + next := Alloc(@bytesof SizeRecord) as [SizeRecord]; + currentSizeRecord.next := next; + end if; + currentSizeRecord := next; + end if; +end sub; + +sub SizeInvariantError() is + SimpleError("variable-size instruction tried to get bigger"); +end sub; + diff --git a/src/cowasm2/types.coh b/src/cowasm2/types.coh index 8911a1ca..110e5931 100644 --- a/src/cowasm2/types.coh +++ b/src/cowasm2/types.coh @@ -22,7 +22,7 @@ var listingFilename: string; var inputFile: FCB; var outputFile: FCB; var listingFile: FCB; -var lineno: uint16 := 1; +var lineno: uint16; var pass: uint8; var lastPass: uint8 := 0;