def p_draw_line(p):
    '''
  DRAW_LINE :
  '''
    global operandsList
    global quadruples
    y2 = operandsList.pop()
    x2 = operandsList.pop()
    y1 = operandsList.pop()
    x1 = operandsList.pop()
    point1 = Operand("point1", (x1.value, y1.value), (x1.type, y1.type),
                     (x1.vAddress, y1.vAddress))
    point2 = Operand("point2", (x2.value, y2.value), (x2.type, y2.type),
                     (x2.vAddress, y2.vAddress))
    if ((y2.type != "int") and (y2.type != "float")) or (
        (x2.type != "int") and (x2.type != "float")) or (
            (y1.type != "int") and
            (y1.type != "float")) or ((x1.type != "int") and
                                      (x1.type != "float")):
        errorQueue.append(
            "Error: " +
            "Failed operation, int or float type parameters expected.")
        print("Error: " +
              "Failed operation, int or float type parameters expected. ")
    else:
        quadruples.addDrawLineCuadruple(point1, point2)
Exemple #2
0
    def test_shifting_c_code(self) -> None:
        hex_insn = PluginInfo.HEX_INSTR_VAR_SYNTAX

        self.assertEqual(
            "((({}) & 0x1fe0) >> 5)".format(hex_insn),
            Operand.make_sparse_mask(
                InstructionEncoding(self.json["A2_combineii"]["Inst"]).operand_masks[
                    "Ii"
                ]
            ),
        )
        self.assertEqual(
            "(((({}) & 0x7f0000) >> 15) | ((({}) & 0x2000) >> 13))".format(
                hex_insn, hex_insn
            ),
            Operand.make_sparse_mask(
                InstructionEncoding(self.json["A2_combineii"]["Inst"]).operand_masks[
                    "II"
                ]
            ),
        )

        self.assertEqual(
            "(((({}) & 0xfff0000) >> 2) | ((({}) & 0x3fff) >> 0))".format(
                hex_insn, hex_insn
            ),
            Operand.make_sparse_mask(
                InstructionEncoding(self.json["A4_ext"]["Inst"]).operand_masks["Ii"]
            ),
        )
Exemple #3
0
 def randomOperand(self):
     operand = Operand()
     for digit in self.digits.keys():
         operand.addDigit(digit, self.digits[digit].randomInt())
     if (self.explicitRange == []):
         return operand
     elif (self.explicitRange != []
           and operand.value() in self.explicitRange):
         return operand
     else:
         return self.randomOperand()
def p_cte(p):
    '''
    CTE : cte_i 
         | cte_f 
         | cte_c
         | null
    '''
    global cteValue
    global cteType
    global operandsList
    global dirAddresses
    global funcName

    cteValue = p[1]
    if isinstance(p[1], int):
        cteType = "int"
    elif isinstance(p[1], float):
        cteType = "float"

    elif p[1] == "null":
        cteType = "string"

    elif isinstance(p[1], str):
        cteType = "char"

    addressTableKey = determineTypeAddressTable(None, cteType, cteValue, None)
    vAddress = dirAddresses[addressTableKey].getAnAddress()
    dirAddresses[addressTableKey].saveAddressData(vAddress, cteValue, cteType)
    #print (str(vAddress) + " : " + str(dirAddresses[addressTableKey].getAddressData(vAddress)["value"]))
    if p[1] == "null":
        cteType = "null"

    consOperand = Operand(None, cteValue, cteType, vAddress)
    operandsList.append(consOperand)
Exemple #5
0
    def validate_function_call(self):
        if self.param_count != self.AT.funcs[
                self.current_function_call].num_params:
            raise NameError(
                f"Wrong number of parameters passed. Expected {self.AT.funcs[self.current_function_call].num_params}. {self.param_count} were given."
            )
        else:
            self.generate_quadruple(
                Operator.GOSUB, self.current_function_call, None,
                self.AT.funcs[self.current_function_call].first_quadruple)

        func = self.AT.get_func(self.current_function_call)

        func_return_type = func.get_return_type()
        if func_return_type is not Type.VOID:
            tmp_address = self.memory_manager.set_temp_address(
                func_return_type)
            temp = Operand(address=tmp_address)
            func_address = self.AT.get_global_var(
                self.current_function_call).get_address()
            self.generate_quadruple(Operator.ASSIGN, func_address, None,
                                    tmp_address)
            self.operands.append(temp)
            self.types.append(func_return_type)
        self.operators.pop()
Exemple #6
0
    def ver_index(self):
        var, dim_num = self.arrays.pop()
        if dim_num == 0:
            self.current_array_address = 0
            self.current_array_dim_number = var.get_dim_count()
        if self.current_dim == self.current_array_dim_number:
            raise NameError(f'Trying to access a non-existent dimension')
        s_address = self.operands.pop().get_address()
        self.types.pop()
        dim = var.get_dim(dim_num)
        lim_inf = self.AT.get_constant_address(dim.get_lim_inf(), Type.INT)
        lim_sup = self.AT.get_constant_address(dim.get_lim_sup(), Type.INT)
        self.generate_quadruple(Operator.VER, s_address, lim_inf, lim_sup)

        # Following the formula s1*m1 + s2 + (-k)....
        tmp_address = self.memory_manager.set_temp_address(Type.INT)
        t = Operand(address=tmp_address, op_type=Type.INT)
        m = dim.get_m()
        m_address = self.AT.get_constant_address(m, Type.INT)
        # If it doesn't exist, create a new constant address for it.
        if m_address == -1:
            m_address = self.memory_manager.set_constant_address(Type.INT)
            self.AT.add_constant_address(m, Type.INT, m_address)
        # Multiply m of the current Dim node if it's not the last dim
        if dim_num < self.current_array_dim_number - 1:
            self.generate_quadruple(Operator.TIMES, s_address, m_address,
                                    tmp_address)
        # Add (-k) if it's the last Dim node
        else:
            k_address = m_address
            self.generate_quadruple(Operator.PLUS, s_address, k_address,
                                    tmp_address)
        if dim_num != 0:
            aux = self.operands.pop()
            self.types.pop()
            tmp_address_2 = self.memory_manager.set_temp_address(Type.INT)
            self.generate_quadruple(Operator.PLUS, aux.get_address(),
                                    tmp_address, tmp_address_2)
            t.set_address(tmp_address_2)
        self.operands.append(t)
        self.types.append(Type.INT)
        self.arrays.append((var, dim_num + 1))
Exemple #7
0
    def maybe_solve_sign(self):
        operator = self.get_top_operator()

        if operator in (Operator.POSITIVE_SIGN, Operator.NEGATIVE_SIGN,
                        Operator.NOT):
            operand = self.operands.pop()
            operand_type = self.types.pop()
            operator = self.operators.pop()
            result_type = semantic_cube[operand_type][operator]
            if result_type == Type.ERROR:
                raise NameError(f'Type mismatch {operand_type} {operator}')
            temp = Operand(op_type=result_type)
            address = self.memory_manager.set_temp_address(result_type)
            temp.set_address(address)
            self.curr_t_count += 1
            self.generate_quadruple(operator, operand.get_address(), None,
                                    temp.get_address())

            self.operands.append(temp)
            self.types.append(result_type)
Exemple #8
0
 def addExpressionCuadruple(self, operator, leftOperand, rightOperand, dirAddresses):
     result_type = SC[leftOperand.type][rightOperand.type][operator]
     if result_type == "error":
         return "Failed operation. type missmatch: cannot do " + operator + " operation between " + leftOperand.type + " and " + rightOperand.type
     else:
         self.resultsCounter += 1
         resultName = "result" + str(self.resultsCounter) 
         addressTableKey = determineTypeAddressTable(None,result_type,None,True)
         vAddress = dirAddresses[addressTableKey].getAnAddress()
         resultOperand = Operand(resultName, None, result_type, vAddress)
         self.quadruples.append( (operator, leftOperand, rightOperand, resultOperand) )
         return resultOperand
Exemple #9
0
    def maybe_solve_operation(self, operations):
        operator = self.get_top_operator()

        if operator in operations:
            r_operand = self.operands.pop()
            r_type = self.types.pop()
            l_operand = self.operands.pop()
            l_type = self.types.pop()
            operator = self.operators.pop()

            result_type = semantic_cube[l_type][r_type][operator]

            if result_type == Type.ERROR:
                raise NameError(f"Type mismatch {l_type} {operator} {r_type}")

            temp = Operand()
            temp.set_type(result_type)
            address = self.memory_manager.set_temp_address(result_type)
            temp.set_address(address)
            self.curr_t_count += 1

            self.operands.append(temp)
            self.types.append(result_type)

            self.generate_quadruple(operator, l_operand.get_address(),
                                    r_operand.get_address(), address)
def p_sem_add_gosub(p):
    '''
    SEM_ADD_GOSUB :
    '''
    global funcCall
    global quadruples
    global operandsList
    global funcDirec
    quadruples.addGosubFuncQuadruple(funcCall)
    funcCallType = funcDirec.getFuncReturnType(funcCall)

    if not funcCallType == "void":
        operandsList.append(Operand(funcCall, None, funcCallType, funcCall))
def p_do_color(p):
    '''
  DO_COLOR : cte_s
  '''

    global dirAddresses
    global operandsList
    global quadruples

    cteValue = p[1]
    cteType = "string"
    addressTableKey = determineTypeAddressTable(None, cteType, cteValue, None)
    vAddress = dirAddresses[addressTableKey].getAnAddress()
    colorOperand = Operand(None, cteValue, cteType, vAddress)
    dirAddresses[addressTableKey].saveAddressData(vAddress, cteValue, cteType)
    quadruples.addColorQuadruple(colorOperand)
def p_sem_add_print_cte_s(p):
    '''
    SEM_ADD_PRINT_CTE_S : cte_s
    '''
    global operandsList
    global quadruples

    global dirAddresses
    global funcName

    cteValue = p[1]
    cteType = "string"
    addressTableKey = determineTypeAddressTable(None, cteType, cteValue, None)
    vAddress = dirAddresses[addressTableKey].getAnAddress()
    consOperand = Operand(None, cteValue, cteType, vAddress)
    dirAddresses[addressTableKey].saveAddressData(vAddress, cteValue, cteType)
    quadruples.addPrintCuadruple(consOperand)
Exemple #13
0
 def get_array_dir(self):
     operand = self.operands.pop()
     var, _ = self.arrays.pop()
     self.types.pop()
     # To make things easy, our tp are normal temporary address but with negative address value
     tmp_address = self.memory_manager.set_temp_address(Type.INT) * -1
     t = Operand(address=tmp_address)
     # Add base address
     base_address = var.get_address()
     const_address = self.AT.get_constant_address(base_address, Type.INT)
     if const_address == -1:  # It doesn't exist.
         const_address = self.memory_manager.set_constant_address(Type.INT)
         self.AT.add_constant_address(base_address, Type.INT, const_address)
     self.generate_quadruple(Operator.PLUS, operand.get_address(),
                             const_address, tmp_address * -1)
     self.operands.append(t)
     self.types.append(Type.INT)
def p_variable(p):
    '''
    VARIABLE : SEM_ID_FOR_ARRAY '[' EXPRESION SEM_CHECK_ARRAY ']' 
              | id
    '''
    global varName
    global funcDirec
    global operandsList
    global funcDirec
    global dirAddresses
    global funcName

    #es una variable en una expresion, no un arreglo
    if len(p) < 3:
        varName = p[1]
        retrievedVar = funcDirec.getVariableInFunc(funcName, varName)
        if isinstance(retrievedVar, str):
            errorQueue.append("Error: " + retrievedVar)
            print("Error: ", retrievedVar)
        else:
            operandsList.append(
                Operand(varName, None, retrievedVar["varType"],
                        retrievedVar["vAddress"]))
Exemple #15
0
 def add_var(self, var_name, is_param=False, is_array=False):
     func = None
     operand = Operand(name=var_name,
                       op_type=types[self.last_var_type],
                       is_array=is_array)
     if self.is_global:
         self.AT.add_global_address(operand)
     else:
         func = self.get_current_func()
         func.add_var(operand)
     if is_param:
         func.num_params += 1
         func.param_names.append(var_name)
     if is_array:
         func.current_var_name = var_name
         self.r = 1
     else:
         # Address is only set for non-arrays for now. Address for arrays should be set after knowing the total needed memory space for the array.
         scope = Scope.GLOBAL if self.is_global else Scope.LOCAL
         var_address = self.memory_manager.set_address(
             scope=scope, var_type=types[self.last_var_type])
         var = self.find_var_in_address_table(var_name)
         var.set_address(var_address)
Exemple #16
0
    def parse(self) -> RecordList:
        record_list = RecordList()

        with open(self.src) as fd:
            for line in fd.readlines():
                line = line.replace('=>', ' ')
                line = line.replace(',', ' ')

                operator, *operand = line.split()
                if operator.startswith("//"):
                    # this is comment line
                    continue

                # remove inline comment
                i = 0
                for i, _ in enumerate(operand):
                    op = operand[i]
                    if op == '//':
                        break
                operand = operand[:i + 1]

                if operator in Operator.NOP_OPERATOR:
                    record_list.append(Record(Operator(operator)))
                elif operator in Operator.UNARY_OPERATOR:
                    record_list.append(
                        Record(Operator(operator), Operand(operand[0])))
                elif operator in Operator.BINARY_OPERATOR:
                    if len(operand) != 2:
                        raise ValueError("invalid operand: {}".format(operand))

                    record_list.append(
                        Record(Operator(operator),
                               operand_one=Operand(operand[0]),
                               operand_three=Operand(operand[1])))
                elif operator in Operator.TRIPLE_OPERATOR:
                    record_list.append(
                        Record(Operator(operator), Operand(operand[0]),
                               Operand(operand[1]), Operand(operand[2])))
                else:
                    raise ValueError("invalid operator: {}".format(operator))

        return record_list
    def parse_instruction(self) -> None:
        """Parses all operands of the instruction which are encoded."""

        # TODO A lot of duplicate code with Instruction::parse:instruction()
        # Operand names seen during parsing the encoding. Twin operands (Operands which appear in high and low instr.)
        # were renamed.

        all_ops = deepcopy(
            self.high_instr.llvm_in_out_operands + self.low_instr.llvm_in_out_operands
        )
        self.llvm_filtered_operands = self.remove_invisible_in_out_regs(
            self.llvm_syntax, all_ops
        )
        self.operand_indices = self.get_syntax_operand_indices(
            self.llvm_syntax, self.llvm_filtered_operands
        )

        # Update syntax indices
        if self.has_new_non_predicate:
            op_name = self.llvm_in_out_operands[self.new_operand_index][1]
            self.new_operand_index = self.operand_indices[op_name]
            # log("{}\n new: {}".format(self.llvm_syntax, self.new_operand_index), LogLevel.DEBUG)
        if self.has_extendable_imm:
            op_name = self.llvm_in_out_operands[self.ext_operand_index][1]
            self.ext_operand_index = self.operand_indices[op_name]
            # log("{}\n ext: {}".format(self.llvm_syntax, self.ext_operand_index), LogLevel.DEBUG)

        if len(self.llvm_filtered_operands) > PluginInfo.MAX_OPERANDS:
            warning = "{} instruction struct can only hold {} operands. This instruction has {} operands.".format(
                PluginInfo.FRAMEWORK_NAME,
                PluginInfo.MAX_OPERANDS,
                len(self.llvm_filtered_operands),
            )
            raise ImplementationException(warning)

        for in_out_operand in self.llvm_filtered_operands:
            op_name = in_out_operand[1]
            op_type = in_out_operand[0]["def"]
            index = self.operand_indices[op_name]

            # Parse register operand
            if Operand.get_operand_type(op_type) is OperandType.REGISTER:
                # Indices of new values (stored in "opNewValue") are only for non predicates.
                is_new_value = (
                    self.new_operand_index == index and self.has_new_non_predicate
                )
                operand = Register(op_name, op_type, is_new_value, index)
                # Whether the predicate registers holds a new value is denoted in "isPredicatedNew".
                if self.predicate_info.new_value and operand.is_predicate:
                    operand.is_new_value = True

            # Parse immediate operands
            elif Operand.get_operand_type(op_type) is OperandType.IMMEDIATE:
                extendable = self.has_extendable_imm and self.ext_operand_index == index
                if self.extendable_alignment > 0:
                    log(str(self.extendable_alignment), op_type)
                operand = Immediate(
                    op_name, op_type, extendable, self.extendable_alignment, index
                )

            else:
                raise ImplementationException(
                    "Unknown operand type: {}, op_name: {}".format(op_type, op_name)
                )

            # Use lower() because we can get RX16in and Rx16in but constraints are always Rx16in.
            if op_name.lower() in self.constraints.lower():
                operand.is_in_out_operand = True
                operand.is_out_operand = True
                operand.is_in_operand = True
            elif in_out_operand in self.llvm_in_operands:
                operand.is_in_operand = True
            elif in_out_operand in self.llvm_out_operands:
                operand.is_out_operand = True

            # Add opcode extraction code
            if (
                operand.type == OperandType.IMMEDIATE and operand.is_constant
            ):  # Constants have no parsing code.
                pass
            else:
                if (
                    operand.is_in_out_operand and op_name[-2:] == "in"
                ):  # In/Out Register
                    mask = self.encoding.operand_masks[op_name[:-2]]  # Ends with "in"
                else:
                    mask = self.encoding.operand_masks[op_name]
                operand.opcode_mask = mask
                operand.add_code_for_opcode_parsing(Operand.make_sparse_mask(mask))

            # On the fly check whether the new values have been assigned correctly.
            if op_name + ".new" in self.llvm_syntax:
                if not operand.is_new_value:
                    raise ImplementationException(
                        "Register has new value in syntax but not as object."
                        + "It has been parsed incorrectly! Are the indices correctly set?"
                        + "Affected instruction: {}".format(self.llvm_syntax)
                    )

            # log("Add operand: {}".format(op_name), LogLevel.DEBUG)
            # TODO This uses the llvm name as key. Maybe use normalized name? Rs16 -> Rs?
            self.operands[op_name] = operand
Exemple #18
0
 def addParamFuncQuadruple(self, param, paramsCounter):
     resultName = "param" + str(paramsCounter) 
     resultOperand = Operand(resultName, None, param.type, param.vAddress)
     self.quadruples.append( ("parameter", param, None, resultOperand) )
def p_sem_check_array(p):
    '''  
  SEM_CHECK_ARRAY : 
  '''
    global idForArray
    global funcDirec
    global operandsList
    global operatorsList
    global funcDirec
    global dirAddresses
    global funcName
    global quadruples

    #checa si existe el arreglo
    retrievedArrayData = funcDirec.getVariableInFunc(funcName, idForArray)
    if isinstance(retrievedArrayData, str):
        errorQueue.append("Error: " + retrievedArrayData)
        print("Error: ", retrievedArrayData)
    elif not retrievedArrayData["isArray"]:
        errorQueue.append("Error: Failed operation. " + "variable " +
                          idForArray + " is not an array")
        print("Error: Failed operation. " + "variable " + idForArray +
              " is not an array")
    else:
        arrayIndexExpression = operandsList.pop()
        #print (arrayIndexExpression.value)
        #print (arrayIndexExpression.type)

        #checa que el index del arreglo sea tipo int
        if arrayIndexExpression.type != "int":
            errorQueue.append(
                "Error: Failed operation. Int type index expected for array " +
                idForArray + ". " + arrayIndexExpression.type +
                "type was received instead.")
            print("Error: ", retrievedVar)

        #si ya recibi un index que es una constante
        if isinstance(arrayIndexExpression.value, int):
            actualAddress = retrievedArrayData[
                "vAddress"] + arrayIndexExpression.value
            #checa que el index tipo int del arreglo se encuentre en el rango de direcciones validas para el arreglo
            if (actualAddress < retrievedArrayData["vAddress"]) or (
                    actualAddress > retrievedArrayData["sLimit"]):
                errorQueue.append("Error: Failed operation. Index " +
                                  arrayIndexExpression.value +
                                  " is out of bounds for array " + idForArray)
                print("Error: ", retrievedVar)
            else:
                operandsList.append(
                    Operand(idForArray, None, retrievedArrayData["varType"],
                            actualAddress))

            #oh sorpresa, el index es una expresion cuyo valor solo se puede conocer en ejecucion, por lo tanto no sabemos el address del arreglo
        else:

            #Guarda la direccion base del arreglo en una direccion temporal
            addressTableKey = determineTypeAddressTable(
                None, "int", retrievedArrayData["vAddress"], None)
            vAddress = dirAddresses[addressTableKey].getAnAddress()
            dirAddresses[addressTableKey].saveAddressData(
                vAddress, retrievedArrayData["vAddress"], "int")

            #Crea un operando que represente la direccion base del arreglo
            baseAddressOperand = Operand(None, retrievedArrayData["vAddress"],
                                         "int", vAddress)

            #Suma el operando de la direccion base con el operando del indicie del arreglo para obtener la verdadera direccion
            realAdressOperand = quadruples.addExpressionCuadruple(
                "+", baseAddressOperand, arrayIndexExpression, dirAddresses)
            funcDirec.addTempVarCountInFunc(funcName, realAdressOperand.type)
            #baseArrayInfo = Operand(idForArray, None, retrievedArrayData["varType"],retrievedArrayData["vAddress"])
            #resultOperand = quadruples.addArrayIndexCuadruple(baseArrayInfo,realAdressOperand)

            #Crea un operando de  resultado con la informacion basica del arreglo (nombre, funcion, direccion base)
            resultOperand = Operand(idForArray, funcName,
                                    retrievedArrayData["varType"],
                                    realAdressOperand.vAddress)
            #y ademas, agregale al operando de resultado la info del operando tipo apuntador que tiene guardada su verdadera direccion (la migaja de pan para encontrar al operando del arreglo en los cuadruplos siguientes y resolver su address correcta en ejecucion)
            resultOperand.fakeAddress = realAdressOperand.vAddress
            quadruples.addArrayIndexCuadruple(resultOperand)
            copyResultOperand = Operand(resultOperand.name,
                                        resultOperand.value,
                                        resultOperand.type,
                                        resultOperand.vAddress)
            copyResultOperand.fakeAddress = realAdressOperand.vAddress
            operandsList.append(copyResultOperand)
Exemple #20
0
    def parse_instruction(self) -> None:
        """Parses all operands of the instruction which are encoded."""

        self.llvm_filtered_operands = self.remove_invisible_in_out_regs(
            self.llvm_syntax, deepcopy(self.llvm_in_out_operands)
        )
        self.operand_indices = self.get_syntax_operand_indices(
            self.llvm_syntax, self.llvm_filtered_operands
        )

        # Update syntax indices
        if self.has_new_non_predicate:
            op_name = self.llvm_in_out_operands[self.new_operand_index][1]
            self.new_operand_index = self.operand_indices[op_name]
            # log("{}\nnew: {}".format(self.llvm_syntax, self.new_operand_index), LogLevel.DEBUG)
        if self.has_extendable_imm:
            op_name = self.llvm_in_out_operands[self.ext_operand_index][1]
            self.ext_operand_index = self.operand_indices[op_name]
            # log("{}\next: {}".format(self.llvm_syntax, self.ext_operand_index), LogLevel.DEBUG)

        if len(self.llvm_filtered_operands) > PluginInfo.MAX_OPERANDS:
            warning = "{} instruction struct can only hold {} operands. This instruction has {} operands.".format(
                PluginInfo.FRAMEWORK_NAME,
                PluginInfo.MAX_OPERANDS,
                len(self.llvm_filtered_operands),
            )
            raise ImplementationException(warning)

        # TODO Some instructions encode some register explicitly in the syntax. At the moment we do not,
        #  but maybe should add them here somehow as registers. Example: J4_cmpeq_fp0_jump_t
        #  But note that they don't seem to have an index attached to them.

        # TODO Parse high/low access of registers.

        for in_out_operand in self.llvm_filtered_operands:
            op_name = in_out_operand[1]
            op_type = in_out_operand[0]["def"]
            syntax_index = self.operand_indices[op_name]

            # Parse register operand
            if Operand.get_operand_type(op_type) is OperandType.REGISTER:
                # Indices of new values (stored in "opNewValue") are only for non predicates.
                is_new_value = (
                    self.new_operand_index == syntax_index
                    and self.has_new_non_predicate
                )
                operand = Register(op_name, op_type, is_new_value, syntax_index)
                # Whether the predicate registers holds a new value is denoted in "isPredicatedNew".
                if self.predicate_info.new_value and operand.is_predicate:
                    operand.is_new_value = True
            # Parse immediate operands
            elif Operand.get_operand_type(op_type) is OperandType.IMMEDIATE:
                extendable = (
                    self.has_extendable_imm and self.ext_operand_index == syntax_index
                )
                operand = Immediate(
                    op_name,
                    op_type,
                    extendable,
                    self.extendable_alignment,
                    syntax_index,
                )

            else:
                raise ImplementationException(
                    "Unknown operand type: {}, op_name: {}".format(op_type, op_name)
                )

            if op_name in self.constraints:
                operand.is_in_out_operand = True
                operand.is_out_operand = True
                operand.is_in_operand = True
            elif in_out_operand in self.llvm_in_operands:
                operand.is_in_operand = True
            elif in_out_operand in self.llvm_out_operands:
                operand.is_out_operand = True

            # Add opcode extraction code
            if (
                operand.type == OperandType.IMMEDIATE and operand.is_constant
            ):  # Constants have no parsing code.
                pass
            else:
                if (
                    operand.is_in_out_operand and op_name[-2:] == "in"
                ):  # In/Out Register
                    mask = self.encoding.operand_masks[op_name[:-2]]  # Ends with "in"
                else:
                    mask = self.encoding.operand_masks[op_name]
                operand.opcode_mask = mask
                operand.add_code_for_opcode_parsing(Operand.make_sparse_mask(mask))

            # On the fly check whether the new values have been assigned correctly.
            if op_name + ".new" in self.llvm_syntax:
                if not operand.is_new_value:
                    raise ImplementationException(
                        "Register has new value in syntax but not as object."
                        + "It has been parsed incorrectly! Are the indices correctly set?"
                        + "Affected instruction: {}".format(self.llvm_syntax)
                    )

            self.operands[op_name] = operand
Exemple #21
0
    def build_operand_object(self, name, is_function_call=False):
        t = type(name)
        operand = Operand(name, is_function_call=is_function_call)

        if t == int:
            operand.set_type(Type.INT)
            address = self.AT.get_constant_address(name, Type.INT)
            if address == -1:  # It doesn't exist.
                address = self.memory_manager.set_constant_address(Type.INT)
                self.AT.add_constant_address(name, Type.INT, address)
            operand.set_address(address)
        elif t == float:
            operand.set_type(Type.FLOAT)
            address = self.AT.get_constant_address(name, Type.FLOAT)
            if address == -1:  # It doesn't exist.
                address = self.memory_manager.set_constant_address(Type.FLOAT)
                self.AT.add_constant_address(name, Type.FLOAT, address)
            operand.set_address(address)
        elif t == str:
            # if constant
            if name[0] == "\"" and name[-1] == "\"":
                operand.set_type(Type.STRING)
                address = self.AT.get_constant_address(name, Type.STRING)
                if address == -1:  # It doesn't exist.
                    address = self.memory_manager.set_constant_address(
                        Type.STRING)
                    self.AT.add_constant_address(name, Type.STRING, address)
                operand.set_address(address)

            else:  # Variable
                var = self.find_var_in_address_table(name)
                if var == -1:
                    raise NameError(f'Undeclared variable {name}')
                operand.set_address(var.get_address())
                operand_type = self.get_type_from_address(var.get_address())
                operand.set_type(operand_type)

        return operand
Exemple #22
0
from Composite import Composite
from Operand import Operand
from Add import Add
from Multiply import Multiply


#(10 + 25) * 4 + 52 * (3 + 6)
expression = Composite(0)

first_brackets = Add(Operand(10), Operand(25))
mul = Multiply(first_brackets, Operand(4))

second_brackets = Add(Operand(3), Operand(6))
mul2 = Multiply(second_brackets, Operand(52))

add = Add(mul, mul2)
expression.add(add)

print(expression.operation())
Exemple #23
0
 def addReturnCuadruple(self,funcName, operand, dirAddresses):
     #addressTableKey = determineTypeAddressTable("global",operand.type,None,None)
     #vAddress = dirAddresses[addressTableKey].getAnAddress()
     resultOperand = Operand(funcName, None, operand.type, funcName)
     self.quadruples.append( ("return", operand, None, resultOperand) )
     return resultOperand
Exemple #24
0
    def __instructions_operands_init__(self):
        self.loopSize = self.xmldoc.getElementsByTagName(
            'loopSize')[0].attributes['value'].value
        print("loop Size: " + self.loopSize)

        self.percentage_clue = self.xmldoc.getElementsByTagName(
            'instruction_percentage_clue')[0].attributes['value'].value
        print("Percentage clue? :" + self.percentage_clue)
        self.instruction_types = {}
        #a dictionary of instruction type and the amount of each instruction in loop.. Note useful only when percentage clue is True
        self.instructions = {}
        #a dictionay that has for keeps an array of instructions for every instruction type
        self.allInstructionArray = []
        #An array which hold all instructions
        self.operands = {}
        self.toggleInstructionsList = {}

        itemList = self.xmldoc.getElementsByTagName("instruction_type")
        for instruction_type in itemList:
            name = instruction_type.attributes["id"].value
            perc = instruction_type.attributes["perc"].value
            self.instruction_types[name] = int(
                float(perc) * float(self.loopSize))
            '''calculate how many of these instructions will be in the loop'''
        if (self.percentage_clue == "True"):
            print("amount per instruction type in the loop:")
            print(self.instruction_types)
            sum = 0
            for value in list(self.instruction_types.values()):
                sum += value
            self.loopSize = sum
            print("actual loop size is " + str(self.loopSize))

        itemList = self.xmldoc.getElementsByTagName("operand")
        print("Available operands\n")
        for operandDesc in itemList:
            ins_type = operandDesc.attributes["type"].value
            if (ins_type == "immediate" or ins_type == "constant"
                    or ins_type == "automatically_incremented_operand"):
                anOperand = Operand(
                    id=operandDesc.attributes["id"].value,
                    type=operandDesc.attributes["type"].value,
                    values=[],
                    min=operandDesc.attributes["min"].value,
                    max=operandDesc.attributes["max"].value,
                    stride=operandDesc.attributes["stride"].value,
                    toggleable=operandDesc.attributes["toggle"].value)
            #elif ins_type=="branch_label":
            #  anOperand = BranchLabel(id=operandDesc.attributes["id"].value,ins_type=operandDesc.attributes["type"].value,values=operandDesc.attributes["values"].value.split(),min=operandDesc.attributes["min"].value,max=operandDesc.attributes["max"].value,stride=operandDesc.attributes["stride"].value,toggleable=operandDesc.attributes["toggle"].value);
            else:
                anOperand = Operand(
                    id=operandDesc.attributes["id"].value,
                    type=operandDesc.attributes["type"].value,
                    values=operandDesc.attributes["values"].value.split(),
                    toggleable=operandDesc.attributes["toggle"].value)

            print("id " + anOperand.id.__str__())
            print("values ")
            print(anOperand.values)
            print("max " + anOperand.max.__str__())
            print("min " + anOperand.min.__str__())
            print("stride " + anOperand.stride.__str__() + "\n")
            self.operands[anOperand.id] = anOperand
        print("End of available operands\n")

        itemList = self.xmldoc.getElementsByTagName("instruction")
        print("Available instructions\n")
        for instructionDesc in itemList:
            name = instructionDesc.attributes["name"].value
            ins_type = instructionDesc.attributes["type"].value
            numOfOperands = instructionDesc.attributes["num_of_operands"].value
            if "format" in instructionDesc.attributes:
                anInstruction = Instruction(
                    name,
                    ins_type,
                    numOfOperands,
                    format=instructionDesc.attributes["format"].value,
                    toggleable=instructionDesc.attributes["toggle"].value)
            else:
                print(
                    "Instruction " + name +
                    "doesnt have format specified.. All instructions must have format... Exitting"
                )
                sys.exit()
                #anInstruction = Instruction(name,ins_type,numOfOperands,toggleable=instructionDesc.attributes["toggle"].value);

            if (instructionDesc.attributes["toggle"].value == "True"):
                self.toggleInstructionsList[
                    instructionDesc.attributes["name"].value] = 1

            operands = []
            #TODO fix this source of bugs..  It's irritating when the num of operands does not match the operands specified in the xml file. and in general is stupid to how the operands specified and the number of operands at the same time.. this redundancy leads to bugs
            for i in range(1, int(anInstruction.numOfOperands) + 1):
                operands.append(self.operands[(
                    instructionDesc.attributes["operand" +
                                               i.__str__()].value)].copy())
            anInstruction.setOperands(operands)
            print(anInstruction)
            ##for debugging
            self.instructions.setdefault(anInstruction.ins_type,
                                         []).append(anInstruction)
        #print (self.instructions);
        print("End of available instructions\n")

        for array in list(self.instructions.values()):
            for ins in array:
                self.allInstructionArray.append(ins)
        print("register initialization")