def test_is_integral_type(self): self.assertTrue(type_utils.is_integral_type('char')) self.assertTrue(type_utils.is_integral_type('short')) self.assertTrue(type_utils.is_integral_type('int')) self.assertTrue(type_utils.is_integral_type('long')) self.assertTrue(type_utils.is_integral_type('long long')) self.assertFalse(type_utils.is_integral_type('void')) self.assertFalse(type_utils.is_integral_type('float')) self.assertFalse(type_utils.is_integral_type('double')) self.assertFalse(type_utils.is_integral_type('long char')) self.assertFalse(type_utils.is_integral_type('short long'))
def to_3ac(self, get_rval=True, include_source=False): # since returns cast value, should only return rvalue _3ac = [SOURCE(self.linerange[0], self.linerange[1])] expression_type = self.expression.get_resulting_type() expression_result = self.expression.to_3ac() _3ac.extend(expression_result['3ac']) return_register = expression_result['rvalue'] # if same, don't cast if self.to_type != expression_type: if type_utils.is_integral_type(self.to_type): new_register = tickets.INT_REGISTER_TICKETS.get() _3ac.append(CVTSW(new_register, return_register)) return_register = new_register else: new_register = tickets.FLOAT_REGISTER_TICKETS.get() _3ac.append(CVTWS(new_register, return_register)) return_register = new_register return {'3ac': _3ac, 'rvalue': return_register}
def to_3ac(self, get_rval=True, include_source=False): _3ac = [] return_type = self.function_symbol.get_resulting_type() if type_utils.is_floating_point_type(return_type): rvalue = tickets.FLOAT_REGISTER_TICKETS.get() else: rvalue = tickets.INT_REGISTER_TICKETS.get() # Call the prologue macro _3ac.append( CALL_PROC(self.function_symbol.identifier, self.function_symbol.activation_frame_size)) # Copy the argument values into for parameter_template, argument in itertools.zip_longest( self.function_symbol.named_parameters, self.arguments): # evaluate the argument expression # get register with value of arg arg_result = argument.to_3ac(get_rval=True) _3ac.extend(arg_result['3ac']) arg_rvalue = arg_result['rvalue'] arg_type = type_utils.INT if arg_rvalue[ 0] == 'i' else type_utils.FLOAT param_type = type_utils.INT if type_utils.is_integral_type( return_type) else type_utils.FLOAT # Get casted value if necessary if arg_type != param_type: if type_utils.is_integral_type(param_type): new_register = tickets.INT_REGISTER_TICKETS.get() _3ac.append(CVTSW(new_register, arg_rvalue)) _3ac.append(KICK(arg_rvalue)) arg_rvalue = new_register else: new_register = tickets.FLOAT_REGISTER_TICKETS.get() _3ac.append(CVTWS(new_register, arg_rvalue)) _3ac.append(KICK(arg_rvalue)) arg_rvalue = new_register # store value at memory location indicated by parameter_template # offset = parameter_template.activation_frame_offset # ^ # likely unnecessary since we are moving the stack pointer as we push arguments # if a bug crops up, be sure to check this out offset = 0 if isinstance(argument, VariableSymbol) and argument.is_array: # Kick the old register in case it was a float register _3ac.append(KICK(arg_rvalue)) # Get a new integer register arg_rvalue = tickets.INT_REGISTER_TICKETS.get() _3ac.append( LA( arg_rvalue, taci.Address(int_literal=-parameter_template. activation_frame_offset, register=tacr.FP))) # Store the base address _3ac.append( STORE(arg_rvalue, taci.Address(int_literal=offset, register=tacr.SP), WORD_SIZE)) _3ac.append( SUB(taci.Register(tacr.SP), taci.Register(tacr.SP), WORD_SIZE)) # Store the total array size _3ac.append( LI(arg_rvalue, argument.size_in_bytes() * argument.array_size)) _3ac.append( STORE(arg_rvalue, taci.Address(int_literal=offset, register=tacr.SP), WORD_SIZE)) _3ac.append( SUB(taci.Register(tacr.SP), taci.Register(tacr.SP), WORD_SIZE)) # Store the size of each dimension for dim in argument.array_dims: _3ac.append(LI(arg_rvalue, dim)) _3ac.append( STORE( arg_rvalue, taci.Address(int_literal=offset, register=tacr.SP), WORD_SIZE)) _3ac.append( SUB(taci.Register(tacr.SP), taci.Register(tacr.SP), WORD_SIZE)) else: # Store the value and move the stack pointer _3ac.append( STORE(arg_rvalue, taci.Address(int_literal=offset, register=tacr.SP), WORD_SIZE)) _3ac.append( SUB(taci.Register(tacr.SP), taci.Register(tacr.SP), WORD_SIZE)) # Kick out the temporary at the end of the argument iterating loop _3ac.append(KICK(arg_rvalue)) # Jump to function body _3ac.append(JAL(self.function_symbol.identifier)) # The function will jump back to this address at this point # Call the epilogue macro _3ac.append(CORP_LLAC(self.function_symbol.activation_frame_size)) # Copy the return value before it gets obliterated _3ac.append( ADD(rvalue, taci.Register(tacr.RV), taci.Register(tacr.ZERO))) # TODO: handle double word returns if we get there return {'3ac': _3ac, 'rvalue': rvalue}
def is_integral_type(source): return type_utils.is_integral_type(source.get_resulting_type())
def to_3ac(self, get_rval=True, include_source=False): _3ac = [] return_type = self.function_symbol.get_resulting_type() if type_utils.is_floating_point_type(return_type): rvalue = tickets.FLOAT_REGISTER_TICKETS.get() else: rvalue = tickets.INT_REGISTER_TICKETS.get() # Call the prologue macro _3ac.append(CALL_PROC(self.function_symbol.identifier, self.function_symbol.activation_frame_size)) # Copy the argument values into for parameter_template, argument in itertools.zip_longest(self.function_symbol.named_parameters, self.arguments): # evaluate the argument expression # get register with value of arg arg_result = argument.to_3ac(get_rval=True) _3ac.extend(arg_result['3ac']) arg_rvalue = arg_result['rvalue'] arg_type = type_utils.INT if arg_rvalue[0] == 'i' else type_utils.FLOAT param_type = type_utils.INT if type_utils.is_integral_type(return_type) else type_utils.FLOAT # Get casted value if necessary if arg_type != param_type: if type_utils.is_integral_type(param_type): new_register = tickets.INT_REGISTER_TICKETS.get() _3ac.append(CVTSW(new_register, arg_rvalue)) _3ac.append(KICK(arg_rvalue)) arg_rvalue = new_register else: new_register = tickets.FLOAT_REGISTER_TICKETS.get() _3ac.append(CVTWS(new_register, arg_rvalue)) _3ac.append(KICK(arg_rvalue)) arg_rvalue = new_register # store value at memory location indicated by parameter_template # offset = parameter_template.activation_frame_offset # ^ # likely unnecessary since we are moving the stack pointer as we push arguments # if a bug crops up, be sure to check this out offset = 0 if isinstance(argument, VariableSymbol) and argument.is_array: # Kick the old register in case it was a float register _3ac.append(KICK(arg_rvalue)) # Get a new integer register arg_rvalue = tickets.INT_REGISTER_TICKETS.get() _3ac.append(LA( arg_rvalue, taci.Address(int_literal=-argument.activation_frame_offset, register=tacr.FP))) # Store the base address _3ac.append(STORE(arg_rvalue, taci.Address(int_literal=offset, register=tacr.SP), WORD_SIZE)) _3ac.append(SUB(taci.Register(tacr.SP), taci.Register(tacr.SP), WORD_SIZE)) # Store the total array size _3ac.append(LI(arg_rvalue, argument.size_in_bytes() * argument.array_size)) _3ac.append(STORE(arg_rvalue, taci.Address(int_literal=offset, register=tacr.SP), WORD_SIZE)) _3ac.append(SUB(taci.Register(tacr.SP), taci.Register(tacr.SP), WORD_SIZE)) # Store the size of each dimension for dim in argument.array_dims: _3ac.append(LI(arg_rvalue, dim)) _3ac.append(STORE(arg_rvalue, taci.Address(int_literal=offset, register=tacr.SP), WORD_SIZE)) _3ac.append(SUB(taci.Register(tacr.SP), taci.Register(tacr.SP), WORD_SIZE)) else: # Store the value and move the stack pointer _3ac.append(STORE(arg_rvalue, taci.Address(int_literal=offset, register=tacr.SP), WORD_SIZE)) _3ac.append(SUB(taci.Register(tacr.SP), taci.Register(tacr.SP), WORD_SIZE)) # Kick out the temporary at the end of the argument iterating loop _3ac.append(KICK(arg_rvalue)) # Jump to function body _3ac.append(JAL(self.function_symbol.identifier)) # The function will jump back to this address at this point # Call the epilogue macro _3ac.append(CORP_LLAC(self.function_symbol.activation_frame_size)) # Copy the return value before it gets obliterated _3ac.append(ADD(rvalue, taci.Register(tacr.RV), taci.Register(tacr.ZERO))) # TODO: handle double word returns if we get there return {'3ac': _3ac, 'rvalue': rvalue}