mirror of
https://github.com/notwa/lips
synced 2024-04-30 00:53:23 -07:00
implement align and skip directives
This commit is contained in:
parent
9a2335fab1
commit
bd0c5f4b34
29
README.md
29
README.md
|
@ -108,25 +108,34 @@ TagLo, TagHi, ErrorEPC, RESERVED
|
|||
|
||||
## Directives
|
||||
|
||||
* BYTE: writes a list of 8-bit numbers until end-of-line.
|
||||
* `.byte {numbers...}`
|
||||
writes a series of 8-bit numbers until end-of-line.
|
||||
be wary of potential alignment issues.
|
||||
|
||||
* HALFWORD: writes a list of 16-bit numbers until end-of-line.
|
||||
* `.halfword {numbers...}`
|
||||
writes a series of 16-bit numbers until end-of-line.
|
||||
be wary of potential alignment issues.
|
||||
|
||||
* WORD: writes a list of 32-bit numbers until end-of-line.
|
||||
* `.word {numbers...}`
|
||||
writes a series of 32-bit numbers until end-of-line.
|
||||
|
||||
* SKIP: takes one or two arguments.
|
||||
* `.align [n] [fill]`
|
||||
aligns the next datum to a `n*2` boundary using `fill` for spacing.
|
||||
if `n` is not given, 2 is implied.
|
||||
if `fill` is not given, 0 is implied.
|
||||
|
||||
* ORG: change the current address for writing to; seeking.
|
||||
for now, this is untested and likely to cause performance issues.
|
||||
* `.skip {n} [fill]`
|
||||
skips the next `n` bytes using `fill` for spacing.
|
||||
if `fill` is not given, no bytes are overwritten,
|
||||
and only the position is changed.
|
||||
|
||||
* `.org {address}`
|
||||
set the current address for writing to; seek.
|
||||
until lips is a little more optimized,
|
||||
be cautious of seeking to large addresses.
|
||||
|
||||
### Unimplemented
|
||||
|
||||
* ALIGN: takes one or two arguments.
|
||||
unlike some other assemblers,
|
||||
ALIGN only affects the first immediately following datum.
|
||||
|
||||
* FLOAT: writes a list of 32-bit floating point numbers until end-of-line.
|
||||
this may not get implemented due to a lack of aliasing in vanilla Lua,
|
||||
and thus accuracy issues.
|
||||
|
|
42
lips.lua
42
lips.lua
|
@ -1,8 +1,5 @@
|
|||
-- lips.lua
|
||||
|
||||
-- instructions: https://github.com/mikeryan/n64dev/tree/master/docs/n64ops
|
||||
-- lexer and parser are somewhat based on http://chunkbake.luaforge.net/
|
||||
|
||||
local assembler = {
|
||||
_DESCRIPTION = 'Assembles MIPS assembly files for the R4300i CPU.',
|
||||
_URL = 'https://github.com/notwa/lips/',
|
||||
|
@ -132,6 +129,7 @@ local instructions = {
|
|||
o: offset
|
||||
b: base
|
||||
i: immediate (infmt 'i', 'j', 'J', and 'k' all write to here)
|
||||
I: index
|
||||
C: constant (given in argument immediately after)
|
||||
F: format constant (given in argument after constant)
|
||||
--]]
|
||||
|
@ -751,14 +749,18 @@ function Parser:directive()
|
|||
if name == 'ORG' then
|
||||
self.dumper:add_directive(name, self:number())
|
||||
elseif name == 'ALIGN' or name == 'SKIP' then
|
||||
local size = self:number()
|
||||
if self:is_EOL() then
|
||||
self.dumper:add_directive(name, size)
|
||||
if self:is_EOL() and name == 'ALIGN' then
|
||||
self.dumper:add_directive(name, 0)
|
||||
else
|
||||
self:optional_comma()
|
||||
self.dumper:add_directive(name, size, self:number())
|
||||
local size = self:number()
|
||||
if self:is_EOL() then
|
||||
self.dumper:add_directive(name, size)
|
||||
else
|
||||
self:optional_comma()
|
||||
self.dumper:add_directive(name, size, self:number())
|
||||
end
|
||||
self:expect_EOL()
|
||||
end
|
||||
self:expect_EOL()
|
||||
elseif name == 'BYTE' or name == 'HALFWORD' or name == 'WORD' then
|
||||
self.dumper:add_directive(name, self:number())
|
||||
while not self:is_EOL() do
|
||||
|
@ -1128,12 +1130,18 @@ function Dumper:add_directive(name, a, b)
|
|||
self.pos = a % 0x80000000
|
||||
self:advance(0)
|
||||
elseif name == 'ALIGN' then
|
||||
t.kind = 'align'
|
||||
t.align = a
|
||||
t.fill = b
|
||||
t.kind = 'ahead'
|
||||
local align = a*2
|
||||
if align == 0 then
|
||||
align = 4
|
||||
elseif align < 0 then
|
||||
self:error('negative alignment')
|
||||
end
|
||||
local temp = self.pos + align - 1
|
||||
t.skip = temp - (temp % align) - self.pos
|
||||
t.fill = t.fill or 0
|
||||
table.insert(self.commands, t)
|
||||
--self.size = size.size + ???
|
||||
self:error('align directive is unimplemented')
|
||||
self:advance(t.skip)
|
||||
elseif name == 'SKIP' then
|
||||
t.kind = 'ahead'
|
||||
t.skip = a
|
||||
|
@ -1273,14 +1281,10 @@ function Dumper:dump()
|
|||
self:write(t)
|
||||
elseif t.kind == 'goto' then
|
||||
self.pos = t.addr
|
||||
elseif t.kind == 'align' then
|
||||
-- TODO: align next instruction to 2*n boundary
|
||||
-- note: traditionally, alignment keeps until .align 0 is given
|
||||
self:error('align directive is unimplemented')
|
||||
elseif t.kind == 'ahead' then
|
||||
if t.fill then
|
||||
for i=1, t.skip do
|
||||
self:write{self.fill}
|
||||
self:write{t.fill}
|
||||
end
|
||||
else
|
||||
self.pos = self.pos + t.skip
|
||||
|
|
Loading…
Reference in New Issue
Block a user