1
0
Fork 0
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:
Connor Olding 2015-11-24 13:23:22 -08:00
parent 9a2335fab1
commit bd0c5f4b34
2 changed files with 42 additions and 29 deletions

View File

@ -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.

View File

@ -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