Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into editor-warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
DerelictDrone committed Nov 13, 2023
2 parents c45d37d + 494d35f commit aed9d35
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 8 deletions.
7 changes: 3 additions & 4 deletions lua/wire/client/hlzasm/hc_codetree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ end
-- Returns free (non-busy) register. Does not check EBP and ESP
function HCOMP:FreeRegister()
-- Try to find a free register
for i=1,6 do
for i=1,#self.RegisterBusy do
if not self.RegisterBusy[i] then return i end
end

Expand Down Expand Up @@ -190,7 +190,7 @@ end
function HCOMP:ReadOperandFromMemory(operands,index)
if operands[index].MemoryPointer.Opcode then -- Parse complex expression
local addrReg,isTemp = self:GenerateLeaf(operands[index].MemoryPointer,true)
operands[index] = { MemoryRegister = addrReg, Temporary = isTemp }
operands[index] = { MemoryRegister = addrReg, Segment = operands[index].Segment, Temporary = isTemp }
self.RegisterBusy[addrReg] = isTemp
return addrReg
else -- Parse an operand
Expand All @@ -202,8 +202,7 @@ function HCOMP:ReadOperandFromMemory(operands,index)
rstackLeaf.Operands[1] = { Register = freeReg }
rstackLeaf.Operands[2] = { Constant = operands[index].MemoryPointer.Stack, Segment = 16 }
self:GenerateLeaf(rstackLeaf)

operands[index] = { MemoryRegister = freeReg, Temporary = true }
operands[index] = { MemoryRegister = freeReg, Segment = operands[index].Segment, Temporary = true }
self.RegisterBusy[freeReg] = true
return addrReg
else -- Generate more than just a stack read
Expand Down
2 changes: 2 additions & 0 deletions lua/wire/client/hlzasm/hc_compiler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ function HCOMP:StartCompile(sourceCode,fileName,writeByteCallback,writeByteCalle
self.Settings.GenerateComments = true -- Generates comments in output listing

-- Code generation settings
self.Settings.AutoBusyRegisters = false -- Automatically preserves or zaps a range of registers for all code leaves that are generated while this is enabled.
self.Settings.AutoBusyRegisterRanges = {}
self.Settings.FixedSizeOutput = false -- Output fixed-size instructions
self.Settings.SeparateDataSegment = false -- Puts all variables into separate data segment
self.Settings.GenerateLibrary = false -- Generate precompiled library
Expand Down
15 changes: 15 additions & 0 deletions lua/wire/client/hlzasm/hc_expression.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ function HCOMP:Expression_ExplictIncDec(opcode,label,returnAfter)
elseif label.Type == "Stack" then
operationLeaf.Operands[1] = { Stack = label.StackOffset }
elseif label.Type == "Register" then
if self.RegisterIdentities[label.Name] == -1 then
self:Error("Attempting to use register variable after zapping it")
end
operationLeaf.Operands[1] = { Register = label.Value }
end
end
Expand Down Expand Up @@ -193,6 +196,9 @@ function HCOMP:Expression_ArrayAccess(label) local TOKEN = self.TOKEN
addressLeaf.Operands[2] = { Constant = {{ Type = TOKEN.IDENT, Data = label.Name, Position = self:CurrentSourcePosition() }} }
operationLeaf = { MemoryPointer = addressLeaf }
elseif label.Type == "Register" then
if self.RegisterIdentities[label.Name] == -1 then
self:Error("Attempting to use register variable after zapping it")
end
addressLeaf.Opcode = "add"
addressLeaf.Operands[1] = arrayOffsetLeaf
addressLeaf.Operands[2] = { Register = label.Value }
Expand Down Expand Up @@ -389,6 +395,9 @@ function HCOMP:Expression_Level3() local TOKEN = self.TOKEN
end
elseif label.Type == "Register" then
-- Register variable
if self.RegisterIdentities[label.Name] == -1 then
self:Error("Attempting to use register variable after zapping it")
end
operationLeaf = { Register = label.Value }
end
end
Expand Down Expand Up @@ -655,6 +664,9 @@ function HCOMP:ConstantExpression_Level3()
-- Pointer to stack value is not a constant
return false
elseif label.Type == "Register" then
if self.RegisterIdentities[label.Name] == -1 then
self:Error("Attempting to use register variable after zapping it")
end
-- Register variable is not a constant
return false
elseif label.Type == "Unknown" then
Expand Down Expand Up @@ -736,6 +748,9 @@ function HCOMP:ConstantExpression_Level3()
-- Stack variables are not constant
return false
elseif label.Type == "Register" then
if self.RegisterIdentities[label.Name] == -1 then
self:Error("Attempting to use register variable after zapping it")
end
-- Register variable is not a constant
return false
elseif label.Type == "Unknown" then
Expand Down
4 changes: 2 additions & 2 deletions lua/wire/client/hlzasm/hc_output.lua
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ RegisterName[22] = "KS"
RegisterName[23] = "LS"
for port=0,1023 do RegisterName[1024+port] = "port"..port end
for reg=0,31 do RegisterName[96+reg] = "R"..reg end

HCOMP.RegisterName = RegisterName

local SegmentRegisterName = {}
SegmentRegisterName[01] = "CS"
Expand All @@ -316,7 +316,7 @@ SegmentRegisterName[14] = "EDI"
SegmentRegisterName[15] = "ESP"
SegmentRegisterName[16] = "EBP"
for reg=0,31 do SegmentRegisterName[17+reg] = "R"..reg end

HCOMP.SegmentRegisterName = RegisterName



Expand Down
50 changes: 50 additions & 0 deletions lua/wire/client/hlzasm/hc_preprocess.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,56 @@ function HCOMP:ParsePreprocessMacro(lineText,macroPosition)
self.SilencedFiles[macroPosition.File] = { Silenced = true, FromParent = false }
elseif pragmaCommand == "includes" or pragmaCommand == "other" then
self.SilencedParents[macroPosition.File] = true
end
elseif pragmaName == "allow" or pragmaName == "zap" then
if not self.Settings.AutoBusyRegisters then
self.Settings.AutoBusyRegisters = true
end
local StartRegister, EndRegister = string.match(macroParameters, "([^,%s]+)%s*,%s*([^,%s]+)")
if StartRegister == nil then
self:Error("Missing register range argument",
macroPosition.Line,macroPosition.Col,macroPosition.File)
end
local StartInd,EndInd = -1,-1
for ind,reg in ipairs(self.RegisterName) do
if reg == StartRegister then
StartInd = ind
end
if reg == EndRegister then
EndInd = ind
break
end
end
if StartInd ~= -1 and EndInd ~= -1 then
table.insert(self.Settings.AutoBusyRegisterRanges,{false,StartInd,EndInd})
else
self:Error(StartRegister .. " to " .. EndRegister .. " is an invalid range!",
macroPosition.Line,macroPosition.Col,macroPosition.File)
end
elseif pragmaName == "disallow" or pragmaName == "preserve" then
if not self.Settings.AutoBusyRegisters then
self.Settings.AutoBusyRegisters = true
end
local StartRegister, EndRegister = string.match(macroParameters, "([^,%s]+)%s*,%s*([^,%s]+)")
if StartRegister == nil then
self:Error("Missing register range argument",
macroPosition.Line,macroPosition.Col,macroPosition.File)
end
local StartInd,EndInd = -1,-1
for ind,reg in ipairs(self.RegisterName) do
if reg == StartRegister then
StartInd = ind
end
if reg == EndRegister then
EndInd = ind
break
end
end
if StartInd ~= -1 and EndInd ~= -1 then
table.insert(self.Settings.AutoBusyRegisterRanges,{true,StartInd,EndInd})
else
self:Error(StartRegister .. " to " .. EndRegister .. " is an invalid range!",
macroPosition.Line,macroPosition.Col,macroPosition.File)
end
end
elseif macroName == "define" then -- #define
Expand Down
59 changes: 57 additions & 2 deletions lua/wire/client/hlzasm/hc_syntax.lua
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,19 @@ function HCOMP:BlockStart(blockType)

-- Create busy registers list
self.BusyRegisters = { false,false,false,false,false,false,true,true }
self.RegisterIdentities = {} -- holds register vars with the identity as key and value as index in busyregisters
for i=#self.BusyRegisters,128 do -- Allows R0-R31 and segment registers to be used, but only if ZAPPED beforehand
self.BusyRegisters[i] = true
end
if self.Settings.AutoBusyRegisters then
for _,range in ipairs(self.Settings.AutoBusyRegisterRanges) do
for i=range[2],range[3] do
if self.RegisterName[i] ~= 'N/A' then
self.BusyRegisters[i] = range[1]
end
end
end
end
end

-- Create a leaf that corresponds to label for BREAK
Expand Down Expand Up @@ -428,7 +441,7 @@ end
--------------------------------------------------------------------------------
function HCOMP:DeclareRegisterVariable()
if self.BlockDepth > 0 then
for reg=1,6 do
for reg=1,#self.BusyRegisters do
if not self.BusyRegisters[reg] then
self.BusyRegisters[reg] = true
return reg
Expand Down Expand Up @@ -614,6 +627,7 @@ function HCOMP:DefineVariable(isFunctionParam,isForwardDecl,isRegisterDecl,isStr
if isRegisterDecl then
label.Type = "Register"
label.Value = self:DeclareRegisterVariable()
self.RegisterIdentities[varName] = label.Value
if isStruct then self:Error("Cannot hold structure variables in registers - yet") end
else
label.Type = "Stack"
Expand Down Expand Up @@ -675,6 +689,7 @@ function HCOMP:DefineVariable(isFunctionParam,isForwardDecl,isRegisterDecl,isStr
if isRegisterDecl then
label.Type = "Register"
label.Value = self:DeclareRegisterVariable()
self.RegisterIdentities[varName] = label.Value
else
label.Type = "Variable"
if isStruct and (pointerLevel > 0) then label.PointerToStruct = true end
Expand Down Expand Up @@ -810,8 +825,48 @@ function HCOMP:Statement() local TOKEN = self.TOKEN
if self:MatchToken(TOKEN.PRESERVE) or self:MatchToken(TOKEN.ZAP) then
local tokenType = self.TokenType
if self.BlockDepth > 0 then
while self:MatchToken(TOKEN.REGISTER) do
while self:MatchToken(TOKEN.REGISTER) or self:MatchToken(TOKEN.IDENT) do
if self.TokenType == TOKEN.IDENT then
if self.RegisterIdentities[self.TokenData] then
if tokenType == TOKEN.PRESERVE then
self:Error("Trying to preserve a register variable")
end
if self.RegisterIdentities[self.TokenData] == -1 then
self:Error("Trying to zap variable twice")
end
self.BusyRegisters[self.RegisterIdentities[self.TokenData]] = tokenType == TOKEN.PRESERVE
self.RegisterIdentities[self.TokenData] = -1 -- so we can error on attempted use after zap
if self:MatchToken(TOKEN.MINUS) then
self:Error("Cannot zap ranges using register variables")
end
else
if tokenType == TOKEN.PRESERVE then
self:Error("Trying to preserve a variable")
end
self:Error("Trying to zap a non register variable")
end
end
if self.TokenType == TOKEN.REGISTER then
local prevTokenData = self.TokenData
self.BusyRegisters[self.TokenData] = tokenType == TOKEN.PRESERVE
if self:MatchToken(TOKEN.MINUS) then -- match range of registers
if self:MatchToken(TOKEN.REGISTER) or self:MatchToken(TOKEN.IDENT) then
if self.TokenType == TOKEN.IDENT then
self:Error("Cannot zap ranges using register variables")
end
if prevTokenData > self.TokenData then
self:Error("Start of register range is greater than end of register range")
end
for i=prevTokenData,self.TokenData do
if self.RegisterName[i] ~= "N/A" then
self.BusyRegisters[i] = tokenType == TOKEN.PRESERVE
end
end
else
self:Error("Invalid register range")
end
end
end
self:MatchToken(TOKEN.COMMA)
end
self:MatchToken(TOKEN.COLON)
Expand Down

0 comments on commit aed9d35

Please sign in to comment.