From 9fab57d4267770c5dd36524445c915e76b2d606a Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 27 Nov 2011 11:31:52 +0000 Subject: Allow if(1){}else{} to compile, optimize if/else --- pp2cc.py | 74 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/pp2cc.py b/pp2cc.py index 045cdb9..040f7c9 100755 --- a/pp2cc.py +++ b/pp2cc.py @@ -132,7 +132,7 @@ class Asm(object): Note that the Zero, Negative and oVerflow flags are modified """ - return self.binary_op("LOAD", register, register, label) + return self.binary_op("LOAD", register, register, label) + " ; NOOP" class LinkedNode(object): """Stores nodes with a reference to the parent""" @@ -622,48 +622,52 @@ class Parse(object): def parseIf(self, linked_node): linked_node.incrementLevel() node = linked_node.node - #lbl_if = self.uniqLbl("if") # if - #lbl_th = self.uniqLbl("th") # then - if node.iffalse: - lbl_el = self.uniqLbl("el") # else - lbl_end = self.uniqLbl("fi") # endif - else: - lbl_end = lbl_fi = self.uniqLbl("fi") # endif - lines = self.parseStatement(node.cond, linked_node) - # unused label, but insert it for clearness if possible - #if len(lines) > 0: - # if not self.asm.has_label(lines[0]): - # lines[0] = self.asm.insert_label(lines[0], lbl_if) - - # if cond is zero, go to else (BEQ branches if Z=0). Do not use CMP - lines.append(self.asm.branch_op("BEQ", lbl_el)) - - # if true... + branch_op = "BEQ" then_block = self.parseStatement(node.iftrue, linked_node) - # required label, so insert a NOOP if necessary - #if len(then_block) > 0: - # if self.asm.has_label(then_block[0]): - # lines.append(self.asm.noop(lbl_th)) - # else: - # then_block[0] = self.asm.insert_label(then_block, lbl_th) - lines += then_block - lines.append(self.asm.branch_op("BRA", lbl_end)) - - # else... if node.iffalse: else_block = self.parseStatement(node.iffalse, linked_node) - if len(else_block) > 0: + # if(x){}else{y} is equivalent to if(!x){} + if not then_block: + # note: else can still be empty, if(x){}else{}, but that is + # handled below with the "if then_block" + then_block = else_block + else_block = [] + # invert result + branch_op = "BNE" + else: + else_block = [] + + # if(x){}else{} is equivalent to x, which do not need the below + if then_block: + if else_block: + lbl_false = self.uniqLbl("el") # else + lbl_end = self.uniqLbl("fi") # endif + else: + lbl_end = lbl_false = self.uniqLbl("fi") # endif + + # if cond is satisfied, go to else (BEQ branches if Z=0, BNE + # branches if Z!=0). Do not use CMP, rely on the status flags set + # set by the condition + lines.append(self.asm.branch_op(branch_op, lbl_false)) + # if true... + lines += then_block + + # else... + if else_block: + # this branch is part of the then block, but include it here to + # avoid redundancy (BRA lbl, lbl: NOOP) + lines.append(self.asm.branch_op("BRA", lbl_end)) + + # XXX this is optimization for labelling else, do it later? if self.asm.has_label(else_block[0]): - lines.append(self.asm.noop(lbl_el)) + lines.append(self.asm.noop(lbl_false)) else: - else_block[0] = self.asm.insert_label(else_block[0], lbl_el) - lines += else_block - # why branch if already at the end of the block? hmm - #lines.append(self.asm.branch_op("BRA", lbl_end)) + else_block[0] = self.asm.insert_label(else_block[0], lbl_false) + lines += else_block - lines.append(self.asm.noop(lbl_end)) + lines.append(self.asm.noop(lbl_end)) return lines def parseReturn(self, linked_node): """Return from a function. For non-void functions the result is in R0""" -- cgit v1.2.1