예제 #1
0
def giveCFGFile(fnode, fileName):
    CFGfileName = fileName + ".cfg"
    CFGFile = open(CFGfileName, "w")

    blockCount = -1
    temp = 0
    for fitem in fnode:
        z = helperForCFG(fitem.name, fitem.paramList)
        CFGFile.write(z)
        x = ASTNode('IF', None, None, [True, fitem.ASTList])
        blocks1 = x.giveBlocks()
        blocks = blocks1[1]
        for i in range(1, len(blocks)):
            CFGFile.write("\n<bb " + str(i + blockCount) + ">\n")
            a = blocks[i]
            if a[-1] == 'IF':
                var, temp, lis = a[0].expand(temp, "")
                CFGFile.write(lis)
                CFGFile.write("if(" + var + ") goto <bb " +
                              str(blockCount + a[1] - 1) + ">\n")
                CFGFile.write("else goto <bb " + str(blockCount + a[2] - 1) +
                              ">\n")
            elif a[-1] == 'GOTO':
                for j in range(0, len(a) - 2):
                    var, temp, lis = a[j].expand(temp, "")
                    CFGFile.write(lis)
                CFGFile.write("goto <bb " +
                              str(blockCount + a[len(a) - 2] - 1) + ">\n")
            else:
                if (fitem.returnSTMT is not None):
                    if (len(fitem.returnSTMT) > 0):
                        var, temp, lis = fitem.returnSTMT[0].expand(temp, "")
                        CFGFile.write(lis)
                    else:
                        CFGFile.write("return\n\n")
                else:
                    CFGFile.write("return\n\n")
        blockCount += len(blocks) - 1
예제 #2
0
def writeFS(f, varSymDict, blockCount):
    li = []
    for i in varSymDict.keys():
        if i[1] == f.name and varSymDict[i][2] == 0:
            li.append(i[0])
    li.sort()
    spaceForF = 0
    varAccessDict = {}
    for i in li:
        if (varSymDict[(i, f.name)][0] == 'int'
                or varSymDict[(i, f.name)][1] > 0):
            spaceForF += 4
        else:
            spaceForF += 8
        varAccessDict[i] = spaceForF
    free_reglist = list(range(18))
    stri = ""
    stri += ('\t.text\t# The .text assembler directive indicates\n')
    stri += ('\t.globl ' + str(f.name) + '\t# The following is the code\n')
    stri += (str(f.name) + ":\n")
    stri += (
        "# Prologue begins\n\tsw $ra, 0($sp)\t# Save the return address\n\tsw $fp, -4($sp)\t# Save the frame pointer\n\tsub $fp, $sp, 8\t# Update the frame pointer\n\tsub $sp, $sp, "
        + str(8 + spaceForF) +
        "\t# Make space for the locals\n# Prologue ends\n")

    spaceForFcpy = spaceForF + 8
    fparams = f.paramList
    for i in fparams:
        if (i[0] == 'int' or i[1] > 0):
            spaceForFcpy += 4
        else:
            spaceForFcpy += 8
        varAccessDict[i[2]] = spaceForFcpy
    newblockCount = blockCount
    x = ASTNode('IF', None, None, [True, f.ASTList])
    blocks1 = x.giveBlocks()
    blocks = blocks1[1]
    for i in range(1, len(blocks)):
        free_reglist = list(range(18))
        # 		this initialisation of free_reglist idk if its true
        stri += ("label" + str(i + blockCount) + ":\n")
        a = blocks[i]
        if a[-1] == 'IF':
            var, free_reglist, lis = a[0].expand_assembly(
                free_reglist, "", varAccessDict, False, i + blockCount)
            stri += lis
            stri += ("\tbne " + num_to_reg(var) + ", $0, label" +
                     str(blockCount + a[1] - 1) + "\n\tj label" +
                     str(blockCount + a[2] - 1) + "\n")
        elif a[-1] == 'GOTO':
            for j in range(0, len(a) - 2):
                var, free_reglist, lis = a[j].expand_assembly(
                    free_reglist, "", varAccessDict, False, i + blockCount)
                stri += lis

            stri += ("\tj label" + str(blockCount + a[len(a) - 2] - 1) + "\n")
        else:
            if (f.returnSTMT is not None):
                if (len(f.returnSTMT) > 0):
                    var, free_reglist, lis = f.returnSTMT[0].expand_assembly(
                        free_reglist, "", varAccessDict, False, i + blockCount)
                    stri += lis

            stri += ("\tj epilogue_" + (str(f.name)) + "\n")
    newblockCount += len(blocks) - 1

    stri += (
        "\n# Epilogue begins\nepilogue_" + str(f.name) + ":\n" +
        "\tadd $sp, $sp, " + str(8 + spaceForF) +
        "\n\tlw $fp, -4($sp)\n\tlw $ra, 0($sp)\n\tjr $ra\t# Jump back to the called procedure\n# Epilogue ends\n"
    )
    return stri, newblockCount