mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-01-21 02:33:24 +00:00
PLASM code optimizations match plasm
This commit is contained in:
parent
ddcdf74dba
commit
c075197c6d
@ -126,9 +126,9 @@ $(PLVM03): vmsrc/plvm03.s vmsrc/soscmd.a
|
||||
# Sample code
|
||||
#
|
||||
test: samplesrc/test.pla samplesrc/testlib.pla $(PLVM) $(PLASM)
|
||||
./$(PLASM) -AMW < samplesrc/test.pla > samplesrc/test.a
|
||||
./$(PLASM) -AMOW < samplesrc/test.pla > samplesrc/test.a
|
||||
acme --setpc 4094 -o $(TEST) samplesrc/test.a
|
||||
./$(PLASM) -AMW < samplesrc/testlib.pla > samplesrc/testlib.a
|
||||
./$(PLASM) -AMOW < samplesrc/testlib.pla > samplesrc/testlib.a
|
||||
acme --setpc 4094 -o $(TESTLIB) samplesrc/testlib.a
|
||||
./$(PLVM) TEST
|
||||
|
||||
|
@ -165,6 +165,12 @@ def emit_const(cval)#0
|
||||
emit_word(cval)
|
||||
fin
|
||||
end
|
||||
def emit_code(bval)#0
|
||||
emit_pending_seq
|
||||
^codeptr = bval
|
||||
codeptr++
|
||||
if codeptr - codebuff > codebufsz; exit_err(ERR_OVER|ERR_CODE|ERR_TABLE); fin
|
||||
end
|
||||
def emit_dlb(offset)#0
|
||||
emit_pending_seq
|
||||
emit_byte($6C)
|
||||
@ -279,16 +285,21 @@ def emit_pending_seq#0
|
||||
// Constant value
|
||||
//
|
||||
is CONST_GROUP
|
||||
if op=>opval == $0000 // ZERO
|
||||
emit_byte($00)
|
||||
elsif op=>opval & $FF00 == $0000 // Constant BYTE
|
||||
emit_byte($2A)
|
||||
emit_byte(op->opval)
|
||||
elsif op=>opval & $FF00 == $FF00 // Constant $FF00 | BYTE
|
||||
emit_byte($5E)
|
||||
emit_byte(op->opval)
|
||||
else // Constant WORD
|
||||
emit_byte($2C)
|
||||
if op->opcode == CONST_CODE
|
||||
if op=>opval == $0000 // ZERO
|
||||
emit_byte($00)
|
||||
elsif op=>opval & $FF00 == $0000 // Constant BYTE
|
||||
emit_byte($2A)
|
||||
emit_byte(op->opval)
|
||||
elsif op=>opval & $FF00 == $FF00 // Constant $FF00 | BYTE
|
||||
emit_byte($5E)
|
||||
emit_byte(op->opval)
|
||||
else // Constant WORD
|
||||
emit_byte($2C)
|
||||
emit_word(op=>opval)
|
||||
fin
|
||||
else // Constant LOAD/STORE/CALL
|
||||
emit_byte(op->opcode)
|
||||
emit_word(op=>opval)
|
||||
fin
|
||||
break
|
||||
|
@ -55,8 +55,8 @@ end
|
||||
// Crunch sequence (peephole optimize)
|
||||
//
|
||||
def crunch_seq(seq, pass)
|
||||
word nextop, nextopnext, opprev, op
|
||||
byte crunched, freeops, shiftcnt
|
||||
word nextop, nextopnext, opprev, op, freeops
|
||||
byte crunched, shiftcnt
|
||||
|
||||
opprev = NULL
|
||||
op = *seq
|
||||
@ -67,18 +67,21 @@ def crunch_seq(seq, pass)
|
||||
when op->opcode
|
||||
is CONST_CODE
|
||||
if op=>opval == 1
|
||||
if nextop>opcode == ADD_CODE
|
||||
op->opcode = INC_CODE
|
||||
freeops = 1
|
||||
if nextop->opcode == ADD_CODE
|
||||
op->opcode = INC_CODE
|
||||
op->opgroup = STACK_GROUP
|
||||
freeops = 1
|
||||
break
|
||||
fin
|
||||
if nextop->opcode == SUB_CODE
|
||||
op->opcode = DEC_CODE
|
||||
op->opgroup = STACK_GROUP
|
||||
freeops = 1
|
||||
break
|
||||
fin
|
||||
if nextop->opcode == SHL_CODE
|
||||
op->opcode = DUP_CODE
|
||||
op->opgroup = STACK_GROUP
|
||||
nextop->opcode = ADD_CODE
|
||||
crunched = 1
|
||||
break
|
||||
@ -86,41 +89,17 @@ def crunch_seq(seq, pass)
|
||||
fin
|
||||
when nextop->opcode
|
||||
is NEG_CODE
|
||||
op=>opval = -(op=>opval)
|
||||
op=>opval = -op=>opval
|
||||
freeops = 1
|
||||
break
|
||||
is COMP_CODE
|
||||
op=>opval = ~(op=>opval)
|
||||
op=>opval = ~op=>opval
|
||||
freeops = 1
|
||||
break
|
||||
is LOGIC_NOT_CODE
|
||||
op=>opval = op=>opval ?? FALSE :: TRUE
|
||||
freeops = 1
|
||||
break
|
||||
is LB_CODE // BPTR_CODE
|
||||
op=>opoffset = op=>opval
|
||||
op->opcode = LAB_CODE
|
||||
op->opgroup = GLOBAL_GROUP
|
||||
freeops = 1
|
||||
break
|
||||
is LW_CODE // WPTR_CODE
|
||||
op=>opoffset = op=>opval
|
||||
op->opcode = LAW_CODE
|
||||
op->opgroup = LOCAL_GROUP
|
||||
freeops = 1
|
||||
break
|
||||
is SB_CODE
|
||||
op=>opoffset = op=>opval
|
||||
op->opcode = SAB_CODE
|
||||
op->opgroup = GLOBAL_GROUP
|
||||
freeops = 1
|
||||
break
|
||||
is SW_CODE
|
||||
op=>opoffset = op=>opval
|
||||
op->opcode = SAW_CODE
|
||||
op->opgroup = GLOBAL_GROUP
|
||||
freeops = 1
|
||||
break
|
||||
is BRFALSE_CODE
|
||||
if op=>opval
|
||||
freeops = -2 // Remove constant and never taken branch
|
||||
@ -148,8 +127,9 @@ def crunch_seq(seq, pass)
|
||||
break
|
||||
is EQ_CODE
|
||||
if not op=>opval
|
||||
op->opcode = LOGIC_NOT_CODE
|
||||
freeops = 1
|
||||
op->opcode = LOGIC_NOT_CODE // Replace ZERO:ISEQ
|
||||
op->opgroup = STACK_GROUP
|
||||
freeops = 1
|
||||
fin
|
||||
break
|
||||
is CONST_CODE // Collapse constant operation
|
||||
@ -230,7 +210,7 @@ def crunch_seq(seq, pass)
|
||||
break
|
||||
wend // End of collapse constant operation
|
||||
fin
|
||||
if pass > 0 and freeops == 0 and op=>opval
|
||||
if pass and not freeops and op=>opval
|
||||
crunched = try_dupify(op)
|
||||
fin
|
||||
break // CONST_CODE
|
||||
@ -239,7 +219,6 @@ def crunch_seq(seq, pass)
|
||||
if op=>opval == 1 << shiftcnt
|
||||
op=>opval = shiftcnt
|
||||
nextop->opcode = SHL_CODE
|
||||
nextop->opgroup = STACK_GROUP
|
||||
break
|
||||
fin
|
||||
next
|
||||
@ -249,11 +228,33 @@ def crunch_seq(seq, pass)
|
||||
if op=>opval == 1 << shiftcnt
|
||||
op=>opval = shiftcnt
|
||||
nextop->opcode = SHR_CODE
|
||||
nextop->opcode = STACK_GROUP
|
||||
break
|
||||
fin
|
||||
next
|
||||
break
|
||||
//
|
||||
// Constant addresses
|
||||
//
|
||||
is LB_CODE
|
||||
op->opcode = LAB_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is LW_CODE
|
||||
op->opcode = LAW_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is SB_CODE
|
||||
op->opcode = SAB_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is SW_CODE
|
||||
op->opcode = SAW_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is ICAL_CODE
|
||||
op->opcode = CALL_CODE
|
||||
freeops = 1
|
||||
break
|
||||
wend
|
||||
break // CONST_CODE
|
||||
is LADDR_CODE
|
||||
@ -262,37 +263,32 @@ def crunch_seq(seq, pass)
|
||||
if nextop=>opnext
|
||||
nextopnext = nextop=>opnext
|
||||
when nextopnext->opcode
|
||||
is ADD_CODE
|
||||
is INDEXB_CODE
|
||||
is INDEXB_CODE // ADD_CODE
|
||||
op=>opoffset = op=>opoffset + nextop=>opval
|
||||
freeops = 2
|
||||
freeops = 2
|
||||
break
|
||||
is INDEXW_CODE
|
||||
op=>opoffset = op=>opoffset + nextop=>opval * 2
|
||||
freeops = 2
|
||||
freeops = 2
|
||||
break
|
||||
wend
|
||||
fin
|
||||
break
|
||||
is LB_CODE
|
||||
op->opcode = LLB_CODE
|
||||
op->opgroup = LOCAL_GROUP
|
||||
freeops = 1
|
||||
op->opcode = LLB_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is LW_CODE
|
||||
op->opcode = LLW_CODE
|
||||
op->opgroup = LOCAL_GROUP
|
||||
freeops = 1
|
||||
op->opcode = LLW_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is SB_CODE
|
||||
op->opcode = SLB_CODE
|
||||
op->opgroup = LOCAL_GROUP
|
||||
freeops = 1
|
||||
op->opcode = SLB_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is SW_CODE
|
||||
op->opcode = SLW_CODE
|
||||
op->opgroup = LOCAL_GROUP
|
||||
freeops = 1
|
||||
op->opcode = SLW_CODE
|
||||
freeops = 1
|
||||
break
|
||||
wend
|
||||
if pass > 0 and not freeops
|
||||
@ -305,50 +301,44 @@ def crunch_seq(seq, pass)
|
||||
if nextop=>opnext
|
||||
nextopnext = nextop=>opnext
|
||||
when nextopnext->opcode
|
||||
is ADD_CODE
|
||||
is INDEXB_CODE
|
||||
is INDEXB_CODE // ADD_CODE
|
||||
op=>opoffset = op=>opoffset + nextop=>opval
|
||||
freeops = 2
|
||||
freeops = 2
|
||||
break
|
||||
is INDEXW_CODE
|
||||
op=>opoffset = op=>opoffset + nextop=>opval * 2
|
||||
freeops = 2
|
||||
freeops = 2
|
||||
break
|
||||
wend
|
||||
fin
|
||||
break
|
||||
is LB_CODE
|
||||
op->opcode = LAB_CODE
|
||||
op->opgroup = GLOBAL_GROUP
|
||||
freeops = 1
|
||||
op->opcode = LAB_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is LW_CODE
|
||||
op->opcode = LAW_CODE
|
||||
op->opgroup = GLOBAL_GROUP
|
||||
freeops = 1
|
||||
op->opcode = LAW_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is SB_CODE
|
||||
op->opcode = SAB_CODE
|
||||
op->opgroup = GLOBAL_GROUP
|
||||
freeops = 1
|
||||
op->opcode = SAB_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is SW_CODE
|
||||
op->opcode = SAW_CODE
|
||||
op->opgroup = GLOBAL_GROUP
|
||||
freeops = 1
|
||||
op->opcode = SAW_CODE
|
||||
freeops = 1
|
||||
break
|
||||
is ICAL_CODE
|
||||
op->opcode = CALL_CODE
|
||||
op->opgroup = GLOBAL_GROUP
|
||||
freeops = 1
|
||||
op->opcode = CALL_CODE
|
||||
freeops = 1
|
||||
break
|
||||
wend
|
||||
if pass > 0 and not freeops
|
||||
if pass and not freeops
|
||||
crunched = try_dupify(op)
|
||||
fin
|
||||
break // GADDR_CODE
|
||||
is LLB_CODE
|
||||
if pass > 0
|
||||
if pass
|
||||
crunched = try_dupify(op)
|
||||
fin
|
||||
break // LLB_CODE
|
||||
@ -443,7 +433,7 @@ def crunch_seq(seq, pass)
|
||||
//
|
||||
// If op is at the start of the sequence, we treat this as a special case.
|
||||
//
|
||||
while freeops > 0
|
||||
while freeops
|
||||
nextop = op=>opnext
|
||||
op=>opnext = freeop_lst
|
||||
freeop_lst = op
|
||||
|
@ -48,6 +48,34 @@ def keymatch
|
||||
loop
|
||||
return ID_TKN
|
||||
end
|
||||
def scannum
|
||||
word num
|
||||
num = 0
|
||||
|
||||
if ^scanptr == '$'
|
||||
repeat
|
||||
scanptr++
|
||||
if ^scanptr >= '0' and ^scanptr <= '9'
|
||||
num = (num << 4) + ^scanptr - '0'
|
||||
elsif ^scanptr >= 'A' and ^scanptr <= 'F'
|
||||
num = (num << 4) + ^scanptr - '7'// 'A'-10
|
||||
elsif ^scanptr >= 'a' and ^scanptr <= 'f'
|
||||
num = (num << 4) + ^scanptr - 'W'// 'a'-10
|
||||
else
|
||||
break
|
||||
fin
|
||||
until not ^scanptr
|
||||
elsif ^scanptr < '0' or ^scanptr > '9'
|
||||
repeat
|
||||
num = num * 10 + ^scanptr - '0'
|
||||
scanptr++
|
||||
until ^scanptr < '0' or ^scanptr > '9'
|
||||
else
|
||||
num = ^scanptr
|
||||
fin
|
||||
return num
|
||||
end
|
||||
|
||||
def scan
|
||||
//
|
||||
// Skip whitespace
|
||||
@ -101,7 +129,7 @@ def scan
|
||||
else
|
||||
break
|
||||
fin
|
||||
until !^scanptr
|
||||
until not ^scanptr
|
||||
break
|
||||
is '\''
|
||||
//
|
||||
@ -121,7 +149,8 @@ def scan
|
||||
is 't'
|
||||
constval = $09; break
|
||||
otherwise
|
||||
constval = ^scanptr
|
||||
constval = scannum
|
||||
scanptr--
|
||||
wend
|
||||
fin
|
||||
if ^(scanptr + 1) <> '\''; exit_err(ERR_INVAL|ERR_CONST); fin
|
||||
@ -149,7 +178,8 @@ def scan
|
||||
is 't'
|
||||
^strconstptr = $09; break
|
||||
otherwise
|
||||
^strconstptr = ^scanptr
|
||||
^strconstptr = scannum
|
||||
scanptr--
|
||||
wend
|
||||
fin
|
||||
strconstptr++
|
||||
|
@ -726,9 +726,9 @@ def parse_stmnt
|
||||
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
|
||||
fin
|
||||
emit_seq(seq)
|
||||
emit_byte(stepdir > 0 ?? ADD_CODE :: SUB_CODE)
|
||||
emit_code(stepdir > 0 ?? ADD_CODE :: SUB_CODE)
|
||||
else
|
||||
emit_byte(stepdir > 0 ?? INC_CODE :: DEC_CODE)
|
||||
emit_code(stepdir > 0 ?? INC_CODE :: DEC_CODE)
|
||||
fin
|
||||
while parse_stmnt
|
||||
nextln
|
||||
@ -737,7 +737,7 @@ def parse_stmnt
|
||||
emit_branch(tag_for)
|
||||
cont_tag = tag_prevcnt
|
||||
emit_tag(break_tag)
|
||||
emit_byte(DROP_CODE)
|
||||
emit_code(DROP_CODE)
|
||||
break_tag = tag_prevbrk
|
||||
stack_loop--
|
||||
break
|
||||
@ -797,7 +797,7 @@ def parse_stmnt
|
||||
emit_tag(tag_of)
|
||||
fin
|
||||
emit_tag(break_tag)
|
||||
emit_byte(DROP_CODE)
|
||||
emit_code(DROP_CODE)
|
||||
break_tag = tag_prevbrk
|
||||
stack_loop--
|
||||
break
|
||||
@ -818,7 +818,7 @@ def parse_stmnt
|
||||
is RETURN_TKN
|
||||
if infunc
|
||||
for i = 1 to stack_loop
|
||||
emit_byte(DROP_CODE)
|
||||
emit_code(DROP_CODE)
|
||||
next
|
||||
seq, cfnvals = parse_list
|
||||
emit_seq(seq)
|
||||
@ -841,7 +841,7 @@ def parse_stmnt
|
||||
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
|
||||
emit_seq(seq)
|
||||
fin
|
||||
emit_byte(RET_CODE)
|
||||
emit_code(RET_CODE)
|
||||
fin
|
||||
break
|
||||
is EOL_TKN
|
||||
@ -871,7 +871,7 @@ def parse_stmnt
|
||||
if seq
|
||||
if token == INC_TKN or token == DEC_TKN
|
||||
emit_seq(seq)
|
||||
emit_byte(token == INC_TKN ?? INC_CODE :: DEC_CODE)
|
||||
emit_code(token == INC_TKN ?? INC_CODE :: DEC_CODE)
|
||||
rewind(idptr)
|
||||
seq, drop = parse_value(NULL, LVALUE)
|
||||
emit_seq(seq)
|
||||
|
@ -105,6 +105,15 @@ word syslibsym = @exports
|
||||
//
|
||||
//asm equates included from cmdstub.s
|
||||
//
|
||||
asm saveX#0
|
||||
STX XREG
|
||||
RTS
|
||||
XREG !BYTE 0
|
||||
end
|
||||
asm restoreX#0
|
||||
LDX XREG
|
||||
RTS
|
||||
end
|
||||
// CALL PRODOS
|
||||
// SYSCALL(CMD, PARAMS)
|
||||
//
|
||||
@ -1367,7 +1376,9 @@ while 1
|
||||
execsys(@cmdln)
|
||||
break
|
||||
is '+'
|
||||
saveX
|
||||
execmod(striptrail(@cmdln))
|
||||
restoreX
|
||||
break
|
||||
otherwise
|
||||
cout('?')
|
||||
|
Loading…
x
Reference in New Issue
Block a user