Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precompile now checks using physical addresses rather than XEIP #60

Merged
merged 4 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 53 additions & 12 deletions lua/wire/zvm/zvm_core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,22 @@ function ZVM:Precompile_Finalize()
if not result then
print("[ZVM ERROR]: "..(message or "unknown error"))
else
for address = self.PrecompileStartXEIP, self.PrecompileXEIP-1 do
-- This should guarantee the physical addresses for things.
local page = self:GetPageByIndex(math.floor(self.PrecompileStartXEIP/128))
local precompileStartPEIP = self.PrecompileStartXEIP
local precompilePEIP = self.PrecompileXEIP
if page.Remapped == 1 then
precompileStartPEIP = page.MappedIndex*128+self.PrecompileStartXEIP%128
precompilePEIP = precompileStartPEIP+(self.PrecompileXEIP-self.PrecompileStartXEIP)
end
for address = precompileStartPEIP, precompilePEIP-1 do
if not self.IsAddressPrecompiled[address] then
self.IsAddressPrecompiled[address] = { }
end
table.insert(self.IsAddressPrecompiled[address],self.PrecompileStartXEIP)
table.insert(self.IsAddressPrecompiled[address],precompileStartPEIP)
end
setfenv(result,self.Env)
self.PrecompiledData[self.PrecompileStartXEIP] = result
self.PrecompiledData[precompileStartPEIP] = result
end

return result
Expand Down Expand Up @@ -455,9 +463,20 @@ function ZVM:Precompile_Step()
-- Check if we crossed the page boundary, if so - repeat the check
if math.floor(self.PrecompileXEIP / 128) ~= self.PrecompilePreviousPage then
self:Emit("VM:SetCurrentPage(%d)",math.floor(self.PrecompileXEIP/128))
self:Emit("if (VM.PCAP == 1) and (VM.CurrentPage.Execute == 0) and")
self:Emit(" (VM.PreviousPage.RunLevel ~= 0) then")
self:Dyn_EmitInterrupt("14",self.PrecompileIP)
self:Emit("if (VM.PCAP == 1) then")
self:Emit("if (VM.CurrentPage.Execute == 0) and (VM.PreviousPage.RunLevel ~= 0) then")
self:Dyn_EmitInterrupt("14",self.PrecompileIP)
self:Emit("end")
local expectedPage = self:GetPageByIndex(math.floor(self.PrecompileXEIP/128))
if expectedPage.MappedIndex ~= math.floor(expectedPage.MappedIndex) then
-- Bad address because MappedIndex is a float, send out an invalid address interrupt if this gets executed(it probably will in a sec)
self:Dyn_EmitInterrupt(15,expectedPage.MappedIndex*128)
end
self:Emit("end")
self:Emit("if (VM.CurrentPage.MappedIndex ~= %d) then",expectedPage.MappedIndex)
-- This page wasn't the expected continuation, we should invalidate this address. (force recompile at this point)
self:Emit("VM:InvalidateVirtualPrecompileAddress(VM.XEIP)")
self:Dyn_EmitBreak(true)
self:Emit("end")
self:Emit("VM:SetPreviousPage(%d)",math.floor(self.PrecompileXEIP/128))

Expand Down Expand Up @@ -619,8 +638,26 @@ function ZVM:Precompile_Step()
return not self.PrecompileBreak
end

-- Helper that will convert virtual => physical for you if necessary and then invalidate them.
function ZVM:InvalidateVirtualPrecompileAddress(Address)
local Page = self:GetPageByIndex(math.floor(Address/128))
local newAddress = Address
if Page.Remapped == 1 then
Address = (Page.MappedIndex*128)+(Address%128)
end
self:InvalidatePrecompileAddress(Address)
end


-- These should be physical addresses.
function ZVM:InvalidatePrecompileAddress(Address)
-- Invalidate precompiled data (Moved so the address will be changed to physical if necessary)
if self.IsAddressPrecompiled[Address] then
for k,v in ipairs(self.IsAddressPrecompiled[Address]) do
self.PrecompiledData[v] = nil
self.IsAddressPrecompiled[Address][k] = nil
end
end
end

--------------------------------------------------------------------------------
-- VM step forward
Expand Down Expand Up @@ -648,9 +685,14 @@ function ZVM:Step(overrideSteps,extraEmitFunction)
self.NIF = nil
end

local address = self.XEIP
if self.CurrentPage.Remapped == 1 then
address = (self.CurrentPage.MappedIndex*128)+(self.XEIP%128)
end

-- Check if current instruction is precompiled
local instructionXEIP = self.XEIP
if self.PrecompiledData[instructionXEIP] or overrideSteps then
local instructionPEIP = address
if self.PrecompiledData[instructionPEIP] or overrideSteps then
-- Precompile next instruction
if overrideSteps then
self:Precompile_Initialize()
Expand All @@ -670,12 +712,11 @@ function ZVM:Step(overrideSteps,extraEmitFunction)
-- Step clock forward (account for precompiling)
self.TMR = self.TMR + 24*8000 -- + overrideSteps*9000
end

-- Execute precompiled instruction
if CLIENT then -- FIXME: hack around crash on PCALL
self.PrecompiledData[self.XEIP]()
self.PrecompiledData[address]()
else
local status,message = pcall(self.PrecompiledData[self.XEIP])
local status,message = pcall(self.PrecompiledData[address])
if not status then
print("[ZVM ERROR]: "..message)
self:Interrupt(5,1)
Expand Down
12 changes: 3 additions & 9 deletions lua/wire/zvm/zvm_features.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
self.LS = 0

-- Extended registers
for reg=0,31 do self["R"..reg] = 0 end

Check warning on line 60 in lua/wire/zvm/zvm_features.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator

Check warning on line 60 in lua/wire/zvm/zvm_features.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator

-- Stack size register
self.ESZ = math.max(0,self.RAMSize-1)
Expand Down Expand Up @@ -291,14 +291,6 @@
return false
end

-- Invalidate precompiled data
if self.IsAddressPrecompiled[Address] then
for k,v in ipairs(self.IsAddressPrecompiled[Address]) do
self.PrecompiledData[v] = nil
self.IsAddressPrecompiled[Address][k] = nil
end
end

-- Do we need to perform page checking
if self.PCAP == 1 and self.MF == 1 then
-- Fetch page
Expand Down Expand Up @@ -351,7 +343,9 @@
end
end

-- Perform I/O operation
-- Invalidate precompiled data (Moved so the address will be changed to physical if necessary)
self:InvalidatePrecompileAddress(Address)
-- Perform I/O operation
if (Address >= 0) and (Address < self.RAMSize) then
self.Memory[Address] = Value
else
Expand All @@ -370,7 +364,7 @@
if self.BusLock == 1 then return false end

-- Write to stack
self:WriteCell(self.ESP+self.SS, Value)

Check warning on line 367 in lua/wire/zvm/zvm_features.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator
self.ESP = self.ESP - 1

-- Stack check
Expand Down Expand Up @@ -398,7 +392,7 @@
return 0
end

local Value = self:ReadCell(self.ESP+self.SS)

Check warning on line 395 in lua/wire/zvm/zvm_features.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator
if Value then return Value
else self:Interrupt(6,self.ESP) return 0 end
end
Expand Down
7 changes: 1 addition & 6 deletions lua/wire/zvm/zvm_opcodes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,8 @@
--------------------------------------------------------------------------------
ZVM.OpcodeTable[70] = function(self) --EXTINT
self:Dyn_EmitState()
self:Emit("VM.IP = %d",(self.PrecompileIP or 0))

Check warning on line 511 in lua/wire/zvm/zvm_opcodes.lua

View workflow job for this annotation

GitHub Actions / lint

"Unnecessary parentheses"

Unnecessary parentheses
self:Emit("VM.XEIP = %d",(self.PrecompileTrueXEIP or 0))

Check warning on line 512 in lua/wire/zvm/zvm_opcodes.lua

View workflow job for this annotation

GitHub Actions / lint

"Unnecessary parentheses"

Unnecessary parentheses
self:Dyn_Emit("VM:ExternalInterrupt(math.floor($1))")
self:Dyn_EmitBreak()
self.PrecompileBreak = true
Expand Down Expand Up @@ -765,7 +765,7 @@
self:Dyn_Emit("end")
end
ZVM.OpcodeTable[98] = function(self) --TIMER
self:Dyn_EmitOperand(string.format("(VM.TIMER+%d*VM.TimerDT)",(self.PrecompileInstruction or 0)))

Check warning on line 768 in lua/wire/zvm/zvm_opcodes.lua

View workflow job for this annotation

GitHub Actions / lint

"Unnecessary parentheses"

Unnecessary parentheses
end
ZVM.OpcodeTable[99] = function(self) --LIDTR
self:Dyn_Emit("VM.IDTR = $1")
Expand Down Expand Up @@ -1128,7 +1128,7 @@
ZVM.OpcodeTable[126] = function(self) --LEA
local emitText = self.OperandEffectiveAddress[self.EmitOperandRM[2]] or "0"
emitText = string.gsub(emitText,"$BYTE",self.EmitOperandByte[2] or "0")
emitText = string.format(string.gsub(emitText,"$SEG","VM[%q]",(self.EmitOperandSegment[2] or "DS")))

Check warning on line 1131 in lua/wire/zvm/zvm_opcodes.lua

View workflow job for this annotation

GitHub Actions / lint

"Unnecessary parentheses"

Unnecessary parentheses
self:Dyn_EmitOperand(emitText)
end
ZVM.OpcodeTable[127] = function(self) --BLOCK
Expand Down Expand Up @@ -1206,12 +1206,7 @@
self:Dyn_EmitInterruptCheck()

self:Dyn_Emit("for address=IDX*128,IDX*128+127 do")
self:Dyn_Emit("if VM.IsAddressPrecompiled[address] then")
self:Dyn_Emit("for k,v in ipairs(VM.IsAddressPrecompiled[address]) do")
self:Dyn_Emit("VM.PrecompiledData[v] = nil")
self:Dyn_Emit("VM.IsAddressPrecompiled[address][k] = nil")
self:Dyn_Emit("end")
self:Dyn_Emit("end")
self:Dyn_Emit("VM:InvalidateVirtualPrecompileAddress(address)")
self:Dyn_Emit("end")
self:Dyn_Emit("else")
self:Dyn_EmitInterrupt("11","IDX")
Expand Down Expand Up @@ -1270,7 +1265,7 @@
self:Dyn_Emit("V = VM:Pop()") -- IRET EIP
self:Dyn_EmitInterruptCheck()

for i=0,31 do

Check warning on line 1268 in lua/wire/zvm/zvm_opcodes.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator
self:Dyn_Emit("V = VM:Pop()") self:Dyn_EmitInterruptCheck() self:Dyn_Emit("VM.R%d = V")
end

Expand Down Expand Up @@ -1732,7 +1727,7 @@
self:Dyn_EmitInterruptCheck()
end
ZVM.OpcodeTable[269] = function(self) --VLEN
local seg1code = self.EmitOperandSegment[1] and "0" or "VM.DS"

Check warning on line 1730 in lua/wire/zvm/zvm_opcodes.lua

View workflow job for this annotation

GitHub Actions / lint

"Unused variable"

Unused variable: seg1code
local seg2code = self.EmitOperandSegment[2] and "0" or "VM.DS"
self:Dyn_Emit("if VM.VMODE == 2 then")
self:Dyn_Emit("$L V = VM:ReadVector2f($2 + %s)",seg2code)
Expand Down
Loading