Пример #1
0
    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'))
Пример #2
0
    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'))
Пример #3
0
    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}
Пример #4
0
    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}
Пример #5
0
    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}
Пример #6
0
    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}