1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-09-29 16:55:22 +00:00

PLASM code optimizations match plasm

This commit is contained in:
David Schmenk 2018-01-08 11:00:56 -08:00
parent ddcdf74dba
commit c075197c6d
6 changed files with 138 additions and 96 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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('?')