def test_is_floating_point_type(self): self.assertTrue(type_utils.is_floating_point_type('float')) self.assertTrue(type_utils.is_floating_point_type('double')) self.assertFalse(type_utils.is_floating_point_type('char')) self.assertFalse(type_utils.is_floating_point_type('short')) self.assertFalse(type_utils.is_floating_point_type('int')) self.assertFalse(type_utils.is_floating_point_type('long')) self.assertFalse(type_utils.is_floating_point_type('long long')) self.assertFalse(type_utils.is_floating_point_type('void')) self.assertFalse(type_utils.is_floating_point_type('long char')) self.assertFalse(type_utils.is_floating_point_type('short double'))
def test_is_floating_point_type(self): self.assertTrue(type_utils.is_floating_point_type('float')) self.assertTrue(type_utils.is_floating_point_type('double')) self.assertFalse(type_utils.is_floating_point_type('char')) self.assertFalse(type_utils.is_floating_point_type('short')) self.assertFalse(type_utils.is_floating_point_type('int')) self.assertFalse(type_utils.is_floating_point_type('long')) self.assertFalse(type_utils.is_floating_point_type('long long')) self.assertFalse(type_utils.is_floating_point_type('void')) self.assertFalse(type_utils.is_floating_point_type('long char')) self.assertFalse(type_utils.is_floating_point_type('short double'))
def to_3ac(self, get_rval=True, include_source=False): output = [tac.SOURCE(self.lineno, self.column)] # Get ticket to copy memory location if type_utils.is_floating_point_type(self.get_resulting_type()): value = tickets.FLOAT_REGISTER_TICKETS.get() else: value = tickets.INT_REGISTER_TICKETS.get() if get_rval: # load the register with the variable's value if self.immutable: output.append(tac.LI(value, taci.Immediate(self.value))) if self.global_memory_location: address = taci.Address(label=self.global_memory_location) else: address = taci.Address( int_literal=-self.activation_frame_offset, register=tacr.FP) output.append(tac.LOAD(value, address, self.size_in_bytes())) return {'3ac': output, 'rvalue': value} else: if self.immutable: raise Exception( 'Immutable symbols should not provide lvalues.') # load the register with the address of the variable if self.global_memory_location: output.append( tac.LA(value, taci.Address(label=self.global_memory_location))) else: # remember, stack grows downward, so look under the FP # LA is probably better for readability than the SUB instruction, but I'm leaving it around in # case a bug crops up output.append( tac.LA( value, taci.Address(int_literal=-self.activation_frame_offset, register=tacr.FP))) # output.append(tac.SUB(value, taci.Register(tacr.FP), self.activation_frame_offset)) # output.append(tac.ADD(value, taci.Register(tacr.FP), self.activation_frame_offset)) # pass return {'3ac': output, 'lvalue': value}
def to_3ac(self, get_rval=True, include_source=False): output = [tac.SOURCE(self.lineno, self.column)] # Get ticket to copy memory location if type_utils.is_floating_point_type(self.get_resulting_type()): value = tickets.FLOAT_REGISTER_TICKETS.get() else: value = tickets.INT_REGISTER_TICKETS.get() if get_rval: # load the register with the variable's value if self.immutable: output.append(tac.LI(value, taci.Immediate(self.value))) if self.global_memory_location: address = taci.Address(label=self.global_memory_location) else: address = taci.Address(int_literal=-self.activation_frame_offset, register=tacr.FP) output.append(tac.LOAD(value, address, self.size_in_bytes())) return {'3ac': output, 'rvalue': value} else: if self.immutable: raise Exception('Immutable symbols should not provide lvalues.') # load the register with the address of the variable if self.global_memory_location: output.append(tac.LA(value, taci.Address(label=self.global_memory_location))) else: # remember, stack grows downward, so look under the FP # LA is probably better for readability than the SUB instruction, but I'm leaving it around in # case a bug crops up output.append(tac.LA(value, taci.Address(int_literal=-self.activation_frame_offset, register=tacr.FP))) # output.append(tac.SUB(value, taci.Register(tacr.FP), self.activation_frame_offset)) # output.append(tac.ADD(value, taci.Register(tacr.FP), self.activation_frame_offset)) # pass return {'3ac': output, 'lvalue': value}
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 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}