OperatorExprAST.py revision 11016:bc759340631f
12SN/A# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 21762SN/A# Copyright (c) 2009 The Hewlett-Packard Development Company 32SN/A# All rights reserved. 42SN/A# 52SN/A# Redistribution and use in source and binary forms, with or without 62SN/A# modification, are permitted provided that the following conditions are 72SN/A# met: redistributions of source code must retain the above copyright 82SN/A# notice, this list of conditions and the following disclaimer; 92SN/A# redistributions in binary form must reproduce the above copyright 102SN/A# notice, this list of conditions and the following disclaimer in the 112SN/A# documentation and/or other materials provided with the distribution; 122SN/A# neither the name of the copyright holders nor the names of its 132SN/A# contributors may be used to endorse or promote products derived from 142SN/A# this software without specific prior written permission. 152SN/A# 162SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu 282665Ssaidi@eecs.umich.edufrom slicc.ast.ExprAST import ExprAST 292665Ssaidi@eecs.umich.edufrom slicc.symbols import Type 302SN/A 312SN/Aclass InfixOperatorExprAST(ExprAST): 326216Snate@binkert.org def __init__(self, slicc, left, op, right): 336216Snate@binkert.org super(InfixOperatorExprAST, self).__init__(slicc) 342SN/A 354046Sbinkertn@umich.edu self.left = left 366216Snate@binkert.org self.op = op 374046Sbinkertn@umich.edu self.right = right 387680Sgblack@eecs.umich.edu 398232Snate@binkert.org def __repr__(self): 408232Snate@binkert.org return "[InfixExpr: %r %s %r]" % (self.left, self.op, self.right) 416216Snate@binkert.org 424776Sgblack@eecs.umich.edu def generate(self, code): 432SN/A lcode = self.slicc.codeFormatter() 443064Sgblack@eecs.umich.edu rcode = self.slicc.codeFormatter() 452SN/A 462SN/A ltype = self.left.generate(lcode) 472SN/A rtype = self.right.generate(rcode) 484776Sgblack@eecs.umich.edu 492SN/A # Figure out what the input and output types should be 502SN/A if self.op in ("==", "!=", ">=", "<=", ">", "<"): 514776Sgblack@eecs.umich.edu output = "bool" 527720Sgblack@eecs.umich.edu if (ltype != rtype): 537720Sgblack@eecs.umich.edu self.error("Type mismatch: left and right operands of " + 545784Sgblack@eecs.umich.edu "operator '%s' must be the same type. " + 557720Sgblack@eecs.umich.edu "left: '%s', right: '%s'", 562SN/A self.op, ltype, rtype) 572SN/A else: 582SN/A expected_types = [] 595784Sgblack@eecs.umich.edu output = None 605784Sgblack@eecs.umich.edu 614046Sbinkertn@umich.edu if self.op in ("&&", "||"): 625866Sksewell@umich.edu # boolean inputs and output 632SN/A expected_types = [("bool", "bool", "bool")] 642SN/A elif self.op in ("<<", ">>"): 654776Sgblack@eecs.umich.edu expected_types = [("int", "int", "int"), 664776Sgblack@eecs.umich.edu ("Cycles", "int", "Cycles")] 674776Sgblack@eecs.umich.edu elif self.op in ("+", "-", "*", "/"): 685034Smilesck@eecs.umich.edu expected_types = [("int", "int", "int"), 695034Smilesck@eecs.umich.edu ("Cycles", "Cycles", "Cycles"), 704776Sgblack@eecs.umich.edu ("Tick", "Tick", "Tick"), 712SN/A ("Cycles", "int", "Cycles"), 724776Sgblack@eecs.umich.edu ("Scalar", "int", "Scalar"), 734776Sgblack@eecs.umich.edu ("int", "bool", "int"), 747720Sgblack@eecs.umich.edu ("bool", "int", "int"), 757720Sgblack@eecs.umich.edu ("int", "Cycles", "Cycles")] 764776Sgblack@eecs.umich.edu else: 778232Snate@binkert.org self.error("No operator matched with {0}!" .format(self.op)) 784776Sgblack@eecs.umich.edu 792SN/A for expected_type in expected_types: 804776Sgblack@eecs.umich.edu left_input_type = self.symtab.find(expected_type[0], Type) 814776Sgblack@eecs.umich.edu right_input_type = self.symtab.find(expected_type[1], Type) 822SN/A 838232Snate@binkert.org if (left_input_type == ltype) and (right_input_type == rtype): 844776Sgblack@eecs.umich.edu output = expected_type[2] 854074Sbinkertn@umich.edu 864776Sgblack@eecs.umich.edu if output == None: 877720Sgblack@eecs.umich.edu self.error("Type mismatch: operands ({0}, {1}) for operator " \ 884776Sgblack@eecs.umich.edu "'{2}' failed to match with the expected types" . 894776Sgblack@eecs.umich.edu format(ltype, rtype, self.op)) 902SN/A 917811Ssteve.reinhardt@amd.com # All is well 922SN/A fix = code.nofix() 936216Snate@binkert.org code("($lcode ${{self.op}} $rcode)") 94 code.fix(fix) 95 return self.symtab.find(output, Type) 96 97class PrefixOperatorExprAST(ExprAST): 98 def __init__(self, slicc, op, operand): 99 super(PrefixOperatorExprAST, self).__init__(slicc) 100 101 self.op = op 102 self.operand = operand 103 104 def __repr__(self): 105 return "[PrefixExpr: %s %r]" % (self.op, self.operand) 106 107 def generate(self, code): 108 opcode = self.slicc.codeFormatter() 109 optype = self.operand.generate(opcode) 110 111 # Figure out what the input and output types should be 112 opmap = {"!": "bool", "-": "int", "++": "Scalar"} 113 if self.op in opmap: 114 output = opmap[self.op] 115 type_in_symtab = self.symtab.find(opmap[self.op], Type) 116 if (optype != type_in_symtab): 117 self.error("Type mismatch: right operand of " + 118 "unary operator '%s' must be of type '%s'. ", 119 self.op, type_in_symtab) 120 else: 121 self.error("Invalid prefix operator '%s'", 122 self.op) 123 124 # All is well 125 fix = code.nofix() 126 code("(${{self.op}} $opcode)") 127 code.fix(fix) 128 129 return self.symtab.find(output, Type) 130