From c075197c6d517ab0fbf594018936892d1e7d3859 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 8 Jan 2018 11:00:56 -0800 Subject: [PATCH] PLASM code optimizations match plasm --- src/makefile | 4 +- src/toolsrc/codegen.pla | 31 ++++++--- src/toolsrc/codeopt.pla | 138 +++++++++++++++++++--------------------- src/toolsrc/lex.pla | 36 ++++++++++- src/toolsrc/parse.pla | 14 ++-- src/vmsrc/cmd.pla | 11 ++++ 6 files changed, 138 insertions(+), 96 deletions(-) diff --git a/src/makefile b/src/makefile index 59870c4..973c0c8 100755 --- a/src/makefile +++ b/src/makefile @@ -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 diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index 69db278..16c8b53 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -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 diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index 4feea6f..1e5f386 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -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 diff --git a/src/toolsrc/lex.pla b/src/toolsrc/lex.pla index 187191a..2a9cae9 100644 --- a/src/toolsrc/lex.pla +++ b/src/toolsrc/lex.pla @@ -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++ diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 3afff31..b7180f0 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -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) diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 79b54a9..2d0dbac 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -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('?')