1
0
mirror of https://github.com/g012/l65.git synced 2024-06-02 12:41:28 +00:00

Allowed reuse of skipped space within sections.

This commit is contained in:
g012 2017-10-01 00:14:11 +02:00
parent 54b5939d8d
commit 40bd38aa7c

View File

@ -32,8 +32,8 @@ M.link = function()
if M.strip then if M.strip then
symbols.__index = function(tab,key) symbols.__index = function(tab,key)
local val = rawget(symbols, key) local val = rawget(symbols, key)
if type(val) == 'table' and val.type == 'section' then if type(val) == 'table' and val.type == 'label' then
val.refcount = (val.refcount or 0) + 1 val.section.refcount = val.section.refcount + 1
end end
return val return val
end end
@ -43,29 +43,43 @@ M.link = function()
end end
symbols.__index = symbols symbols.__index = symbols
local chunk_reserve = function(chunks, chunk_ix, chunk, start, size) local chunk_reserve = function(section, chunk_ix)
if start == chunk.start then local chunks = section.location.chunks
if size == chunk.size then chunks[chunk_ix] = nil local chunk = chunks[chunk_ix]
else chunk.start=start+size chunk.size=chunk.size-size end local holes = section.holes
else local new_chunks,ins = {},table.insert
if chunk.size - (start - chunk.start) == size then chunk.size = chunk.size - size
else local chunk1 = { id=id(), start=chunk.start, size=section.org-chunk.start }
local sz = start - chunk.start local hole_ix = 1
table.insert(chunks, chunk_ix+1, { start=start+size, size=chunk.size-(sz+size) }) local hole1 = holes[1]
chunk.size = sz if hole1 and hole1.start==0 then
end chunk1.size = chunk1.size + hole1.size
hole_ix = 2
end end
if chunk1.size > 0 then ins(new_chunks, chunk1) end
while hole_ix <= #holes do
local hole = holes[hole_ix]
local chunki = { id=id(), start=section.org+hole.start, size=hole.size }
ins(new_chunks, chunki)
hole_ix = hole_ix + 1
end
local chunkl = { id=id(), start=section.org+section.size, size=chunk.start+chunk.size-(section.org+section.size) }
local chunkn = new_chunks[#new_chunks]
if chunkn and chunkn.start+chunkn.size==chunkl.start then
chunkn.size = chunkn.size + chunkl.size
elseif chunkl.size > 0 then
ins(new_chunks, chunkl)
end
table.remove(chunks, chunk_ix)
for i=chunk_ix,chunk_ix+#new_chunks-1 do ins(chunks, i, new_chunks[i-chunk_ix+1]) end
end end
local position_section = function(section, constrain) local position_section = function(section, constrain)
local location = section.location local location = section.location
local rorg = location.rorg local chunks,rorg = location.chunks,location.rorg
local chunks = {} table.sort(chunks, function(a,b) return a.size==b.size and a.id<b.id or a.size<b.size end)
for _,chunk in ipairs(location.chunks) do for chunk_ix,chunk in ipairs(chunks) do if chunk.size >= section.size then
if chunk.size >= section.size then chunks[#chunks+1] = chunk end
end
table.sort(chunks, function(a,b) return a.size < b.size end)
for chunk_ix,chunk in ipairs(chunks) do
local waste,position,position_end = math.maxinteger local waste,position,position_end = math.maxinteger
local usage_lowest = function(start, finish) local usage_lowest = function(start, finish)
local inc=1 local inc=1
@ -120,14 +134,14 @@ M.link = function()
usage_lowest(start, chunk.start + chunk.size - section.size) usage_lowest(start, chunk.start + chunk.size - section.size)
end end
if position then if position then
chunk_reserve(location.chunks, chunk_ix, chunk, position, section.size)
section.org = position section.org = position
chunk_reserve(section, chunk_ix)
symbols[section.label] = rorg(position) symbols[section.label] = rorg(position)
--print(section.label, string.format("%04X\t%d", position, section.size)) --print(section.label, string.format("%04X\t%d", position, section.size))
--for k,v in ipairs(location.chunks) do print(string.format(" %04X %04X %d", v.start, v.size+v.start-1, v.size)) end --for k,v in ipairs(location.chunks) do print(string.format(" %04X %04X %d", v.start, v.size+v.start-1, v.size)) end
return position return position
end end
end end end
end end
local sibling_sections = {} local sibling_sections = {}
@ -174,7 +188,7 @@ M.link = function()
end end
for chunk_ix,chunk in ipairs(location.chunks) do for chunk_ix,chunk in ipairs(location.chunks) do
if chunk.start <= section.org and chunk.size - (section.org - chunk.start) >= section.size then if chunk.start <= section.org and chunk.size - (section.org - chunk.start) >= section.size then
chunk_reserve(location.chunks, chunk_ix, chunk, section.org, section.size) chunk_reserve(section, chunk_ix)
symbols[section.label] = rorg(section.org) symbols[section.label] = rorg(section.org)
goto chunk_located goto chunk_located
end end
@ -362,7 +376,7 @@ M.location = function(start, finish)
location.sections = {} -- TODO remove location.sections = {} -- TODO remove
if not location.rorg then location.rorg = function(x) return x end end if not location.rorg then location.rorg = function(x) return x end end
local size = (location.finish or math.huge) - location.start + 1 local size = (location.finish or math.huge) - location.start + 1
location.chunks={ { start=location.start, size=size } } location.chunks={ { id=id(), start=location.start, size=size } }
locations[#locations+1] = location locations[#locations+1] = location
M.location_current = location M.location_current = location
return location return location
@ -394,6 +408,8 @@ M.section = function(t)
section.instructions = {} section.instructions = {}
assert(name:sub(1,1) ~= '_', "sections can't be named with a local label") assert(name:sub(1,1) ~= '_', "sections can't be named with a local label")
section.label = M.label(name) section.label = M.label(name)
section.holes = {}
section.refcount = 0
function section:compute_size() function section:compute_size()
local instructions = self.instructions local instructions = self.instructions
self.size=0 self.cycles=0 self.size=0 self.cycles=0
@ -461,9 +477,13 @@ end
-- relocatable sections. -- relocatable sections.
M.skip = function(bytes) M.skip = function(bytes)
local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) } local l65dbg = { info=debug.getinfo(2, 'Sl'), trace=debug.traceback(nil, 1) }
local size = function() return bytes end local ins,section = {},M.section_current
local bin = function(filler) return nil,bytes end ins.size = function()
table.insert(M.section_current.instructions, { size=size, bin=bin }) table.insert(section.holes, { start=ins.offset, size=bytes })
return bytes
end
ins.bin = function(filler) return nil,bytes end
table.insert(section.instructions, ins)
end end
-- sleep(cycles [, noillegal]) -- sleep(cycles [, noillegal])
@ -782,7 +802,7 @@ for k,_ in pairs(opzab) do
ins.bin = function() local l65dbg=l65dbg ins.bin = function() local l65dbg=l65dbg
local x = word_normalize(late(early or 0)) local x = word_normalize(late(early or 0))
-- since we assumed absolute on link phase, we must generate absolute in binary -- since we assumed absolute on link phase, we must generate absolute in binary
if x <= 0xff and opzpg[k] then print("warning: forcing abs on zpg operand for opcode " .. k) end if x <= 0xff and opzpg[k] then io.stderr:write("warning: forcing abs on zpg operand for opcode " .. k) end
return { abs.opc, x&0xff, x>>8 } return { abs.opc, x&0xff, x>>8 }
end end
table.insert(M.section_current.instructions, ins) table.insert(M.section_current.instructions, ins)
@ -850,7 +870,7 @@ for k,_ in pairs(opzax) do
ins.bin = function() local l65dbg=l65dbg ins.bin = function() local l65dbg=l65dbg
local x = word_normalize(late(early or 0)) local x = word_normalize(late(early or 0))
-- since we assumed absolute on link phase, we must generate absolute in binary -- since we assumed absolute on link phase, we must generate absolute in binary
if x <= 0xff and opzpx[k] then print("warning: forcing abx on zpx operand for opcode " .. k) end if x <= 0xff and opzpx[k] then io.stderr:write("warning: forcing abx on zpx operand for opcode " .. k) end
return { abx.opc, x&0xff, x>>8 } return { abx.opc, x&0xff, x>>8 }
end end
table.insert(M.section_current.instructions, ins) table.insert(M.section_current.instructions, ins)
@ -917,7 +937,7 @@ for k,_ in pairs(opzay) do
ins.bin = function() local l65dbg=l65dbg ins.bin = function() local l65dbg=l65dbg
local x = word_normalize(late(early or 0)) local x = word_normalize(late(early or 0))
-- since we assumed absolute on link phase, we must generate absolute in binary -- since we assumed absolute on link phase, we must generate absolute in binary
if x <= 0xff and opzpy[k] then print("warning: forcing aby on zpy operand for opcode " .. k) end if x <= 0xff and opzpy[k] then io.stderr:write("warning: forcing aby on zpy operand for opcode " .. k) end
return { aby.opc, x&0xff, x>>8 } return { aby.opc, x&0xff, x>>8 }
end end
table.insert(M.section_current.instructions, ins) table.insert(M.section_current.instructions, ins)