Commit 9fe58573 authored by Tom Zhao's avatar Tom Zhao
Browse files

xz1919: merging with develop

parents 3b7cb2dd c5cf0eba
......@@ -18,13 +18,14 @@ helpFunction()
exit 1
}
while getopts "pto:axh" opt
while getopts "pto:axhi" opt
do
case $opt in
p ) PARSE_ONLY="--parse_only" ;;
t ) PRINT_AST="--print_ast" ;;
o ) OPTIMISE="--optimise $OPTARG" ;;
a ) ASSEMBLY="--assembly" ;;
i ) INTEL="--intel" ;;
x ) EXECUTE="--execute" ;;
h ) helpFunction ;;
? ) helpFunction ;; # Print helpFunction in case parameter is non-existent
......@@ -40,4 +41,4 @@ fi
# compile the given wacc file here
# default as using -o1 optimise and generate assembly
java -cp ./bin:./lib/antlr-4.9.1-complete.jar Compiler $1 $PARSE_ONLY $PRINT_AST $OPTIMISE "--optimise" "1" "--assembly" $EXECUTE
\ No newline at end of file
java -cp ./bin:./lib/antlr-4.9.1-complete.jar Compiler $1 $PARSE_ONLY $PRINT_AST $OPTIMISE "--optimise" "1" "--assembly" $EXECUTE $INTEL
......@@ -47,4 +47,4 @@ for folder in ${VALID_EXAMPLES[@]}; do
echo "========================================================================================"
echo "Test Folder" $folder "has been processed" "($COUNTER / $(($TOTAL_COUNT)))"
echo "========================================================================================"
done
\ No newline at end of file
done
#!/bin/bash
VALID_EXAMPLES=(
#"/advanced"
#"/array"
"/basic"
"/expressions"
#"/function"
"/if"
"/IO"
#"/pairs"
#"/runtimeErr"
"/scope"
"/sequence"
"/variables"
"/while"
)
EXECUTE_OUTPUT_DIR="./log/output"
ASSEMBLY_OUTPUT_DIR="./log/assembly/intel"
VALID_EXAMPLES_SRC_DIR="./src/test/examples/valid"
REF_COMPILE="./src/test/examples/refCompile"
mkdir log
mkdir $EXECUTE_OUTPUT_DIR
mkdir log/assembly
mkdir $ASSEMBLY_OUTPUT_DIR
# counters to represent the total number of test files to be processed
TOTAL_COUNT=$(find "${VALID_EXAMPLES[@]/#/${VALID_EXAMPLES_SRC_DIR}}" -name "*.wacc" | wc -l)
COUNTER=0
for folder in ${VALID_EXAMPLES[@]}; do
ASSEMBLY_OUTPUT_VALID_FOLDER="${ASSEMBLY_OUTPUT_DIR}${folder}"
OUTPUT_VALID_FOLDER="${EXECUTE_OUTPUT_DIR}${folder}"
mkdir $ASSEMBLY_OUTPUT_VALID_FOLDER
mkdir $OUTPUT_VALID_FOLDER
for file in $(find "${VALID_EXAMPLES_SRC_DIR}${folder}" -name "*.wacc")
do
FILE_NAME=$(basename "${file%.*}")
EXECUTABLE_OUTPUT_FILE="${OUTPUT_VALID_FOLDER}/${FILE_NAME}.output.txt"
EXECUTABLE_FILE_NAME="${ASSEMBLY_OUTPUT_VALID_FOLDER}/${FILE_NAME}"
echo $file
./compile -i $file 2> "${EXECUTABLE_FILE_NAME}.log.txt"
mv "${FILE_NAME}.s" "${EXECUTABLE_FILE_NAME}.s"
gcc "${EXECUTABLE_FILE_NAME}.s" -o "${EXECUTABLE_FILE_NAME}"
./"${EXECUTABLE_FILE_NAME}" > "${EXECUTABLE_OUTPUT_FILE}"
# Generate the result from reference compiler
cat <(echo "N" | $REF_COMPILE $file -x) | awk '/===========================================================/ {x=!x; if(x) next} x==1 {print}' > temp
# Use the result generated by our compiler
OUR_RESULT=$EXECUTABLE_OUTPUT_FILE
# Compare them to see the differences
diff <(cat temp) <(cat $OUR_RESULT)
ret=$?
(( COUNTER += 1 ))
echo "$COUNTER / $(($TOTAL_COUNT)) files have been executed"
done
echo "========================================================================================"
echo "Test Folder" $folder "has been processed" "($COUNTER / $(($TOTAL_COUNT)))"
echo "========================================================================================"
done
import backend.ARMInstructionGenerator;
import backend.ARMInstructionPrinter;
import backend.directives.CodeSegment;
import backend.directives.DataSegment;
import backend.directives.TextSegment;
import backend.InstructionGenerator;
import backend.InstructionPrinter;
import backend.arm.ARMInstructionGenerator;
import backend.arm.ARMInstructionPrinter;
import backend.arm.segment.CodeSegment;
import backend.arm.segment.DataSegment;
import backend.arm.segment.TextSegment;
import backend.intel.IntelInstructionGenerator;
import backend.intel.IntelInstructionPrinter;
import backend.intel.section.CodeSection;
import backend.intel.section.DataSection;
import backend.intel.section.IntelAsmHeader;
import frontend.ASTPrinter;
import frontend.SemanticChecker;
import frontend.antlr.WACCLexer;
......@@ -14,13 +21,17 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import optimize.ConstantPropagation;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import utils.NodeVisitor;
import utils.Utils.AssemblyArchitecture;
import utils.frontend.ParserErrorHandler;
public class Compiler {
......@@ -63,7 +74,11 @@ public class Compiler {
Node program;
// If the `--parse_only` flag is specified, then we do not run semantic analysis
if (!cmd_ops.contains("--parse_only")) {
SemanticChecker semanticChecker = new SemanticChecker(new HashSet<>());
AssemblyArchitecture arch = AssemblyArchitecture.ARMv6;
if (cmd_ops.contains("--intel")) {
arch = AssemblyArchitecture.Intelx86;
}
SemanticChecker semanticChecker = new SemanticChecker(new HashSet<>(), arch);
semanticChecker.setPath(file.getParent() + "/");
program = semanticChecker.visitProgram(tree);
......@@ -76,45 +91,70 @@ public class Compiler {
break;
case "1":
System.out.println("optimising using const propagate");
NodeVisitor<Node> constPropOptimiser = new ConstantPropagation();
NodeVisitor<Node> constPropOptimiser = new ConstantPropagation(arch);
program = constPropOptimiser.visit(program);
break;
default:
System.out.println("unsupported optimisation level: " + optimise_level);
}
}
/* print optimised ast tree */
if (cmd_ops.contains("--print_ast")) {
ASTPrinter painter = new ASTPrinter();
painter.visit(program);
}
switch (optimise_level) {
case "0":
break;
case "1":
NodeVisitor<Node> constPropOptimiser = new ConstantPropagation(arch);
program = constPropOptimiser.visit(program);
break;
default:
System.out.println("unsupported optimisation level: " + optimise_level);
}
/* print optimised ast tree */
if (cmd_ops.contains("--print_ast")) {
ASTPrinter painter = new ASTPrinter();
painter.visit(program);
}
if (cmd_ops.contains("--assembly")) {
ARMInstructionGenerator generator = new ARMInstructionGenerator();
generator.visit(program);
DataSegment data = new DataSegment(generator.getDataSegmentMessages());
TextSegment text = new TextSegment();
CodeSegment code = new CodeSegment(generator.getInstructions());
ARMInstructionPrinter printer = new ARMInstructionPrinter(data, text, code,
ARMInstructionPrinter.OptimizationLevel.NONE);
if (cmd_ops.contains("--assembly")) {
InstructionGenerator generator = null;
InstructionPrinter printer = null;
if (cmd_ops.contains("--intel")) {
generator = new IntelInstructionGenerator();
generator.visit(program);
IntelAsmHeader header = new IntelAsmHeader("main");
DataSection data = new DataSection(
((IntelInstructionGenerator) generator).getDataSection());
CodeSection code = new CodeSection(
((IntelInstructionGenerator) generator).getInstructions());
printer = new IntelInstructionPrinter(header, data, code);
} else {
generator = new ARMInstructionGenerator();
generator.visit(program);
DataSegment data = new DataSegment(
((ARMInstructionGenerator) generator).getDataSegmentMessages());
TextSegment text = new TextSegment();
CodeSegment code = new CodeSegment(
((ARMInstructionGenerator) generator).getInstructions());
printer = new ARMInstructionPrinter(data, text, code,
ARMInstructionPrinter.OptimizationLevel.NONE);
}
File asmFile = new File(sourceFile.getName().replaceFirst("[.][^.]+$", "") + ".s");
File asmFile = new File(sourceFile.getName().replaceFirst("[.][^.]+$", "") + ".s");
System.out.println("Assembly file created!");
try (FileWriter asmWriter = new FileWriter(asmFile)) {
asmWriter.write(printer.translate());
asmWriter.close();
System.out.println("Assembly has been written to the file!");
System.out.println("Assembly file created!");
try (FileWriter asmWriter = new FileWriter(asmFile)) {
asmWriter.write(printer.translate());
asmWriter.close();
System.out.println("Assembly has been written to the file!");
}
} else {
System.out.println("File already exists");
}
} else {
System.out.println("File already exists");
}
}
} catch (FileNotFoundException e) {
} catch (FileNotFoundException e){
System.out.println("ERROR in Compile.java: the given file '" + args[0] + "' is not found.");
} catch (IOException e) {
} catch (IOException e){
System.out.println("ERROR in Compile.java: IOException has been raised in Compile.java");
}
}
......
package backend;
public interface Instruction {
public abstract String assemble();
}
package backend;
import backend.arm.ARMInstructionGenerator;
import backend.arm.instructions.ARMInstruction;
import backend.common.LabelInstruction;
import backend.intel.IntelInstructionGenerator;
import backend.intel.instructions.IntelInstruction;
import java.util.ArrayList;
import java.util.List;
import utils.NodeVisitor;
import utils.frontend.symbolTable.SymbolTable;
public abstract class InstructionGenerator<T extends Instruction> implements NodeVisitor<Void> {
/* the code section of the assembly code */
protected final List<T> instructions;
/* record the current symbolTable used during instruction generation */
protected SymbolTable currSymbolTable;
/* record the symbolTable of the innermost loop */
protected SymbolTable currForLoopSymbolTable;
/* mark if we are visiting a lhs or rhs of an expr */
protected boolean isLhs;
/* offset used when pushing variable in stack in visitFunctionCall
* USED FOR evaluating function parameters, not for changing parameters' offset in function body*/
protected int stackOffset;
/* used by visitFunc and visitReturn, set how many byte this function used on stack
accumulated, on enter a new scope, decrease on exit
no need to distinguish function and non function scope, as non function scope does not call return */
protected int funcStackSize;
/* recording the jump-to label for branching statement, i.e. break, continue */
protected LabelInstruction currBreakJumpToLabel;
protected LabelInstruction currContinueJumpToLabel;
public InstructionGenerator() {
instructions = new ArrayList<>();
currSymbolTable = null;
stackOffset = 0;
isLhs = false;
currBreakJumpToLabel = null;
currContinueJumpToLabel = null;
currForLoopSymbolTable = null;
}
}
package backend;
public abstract class InstructionPrinter {
public abstract String translate();
}
......@@ -12,7 +12,7 @@ BIN_FRONTEND_DIR := $(ROOT_DIR)/bin/frontend
# Tools
FIND := find
RM := rm -rf
RM := rm -rf
MKDIR := mkdir -p
JAVA := java
JAVAC := javac
......
package backend;
import static backend.instructions.LDR.LdrMode.*;
import static backend.instructions.STR.StrMode.*;
import static backend.instructions.addressing.AddressingMode2.AddrMode2.*;
import static backend.instructions.arithmeticLogic.ArithmeticLogic.unopInstruction;
import static backend.instructions.operand.Immediate.BitNum.CONST8;
import static backend.instructions.operand.Operand2.Operand2Operator.*;
package backend.arm;
import static backend.arm.instructions.LDR.LdrMode.*;
import static backend.arm.instructions.STR.StrMode.*;
import static backend.arm.instructions.addressing.AddressingMode2.AddrMode2.*;
import static backend.arm.instructions.arithmeticLogic.ARMArithmeticLogic.armUnopAsm;
import static backend.arm.instructions.addressing.ARMImmediate.BitNum.CONST8;
import static backend.arm.instructions.addressing.Operand2.Operand2Operator.*;
import static frontend.node.expr.UnopNode.Unop.MINUS;
import static utils.Utils.RoutineInstruction;
import static utils.Utils.RoutineInstruction.*;
import static utils.Utils.SystemCallInstruction.*;
import static utils.Utils.*;
import static utils.backend.ARMInstructionRoutines.routineFunctionMap;
import static backend.arm.instructions.ARMInstructionRoutines.routineFunctionMap;
import static utils.backend.Cond.*;
import static utils.backend.register.ARMConcreteRegister.*;
import backend.instructions.*;
import backend.instructions.LDR.LdrMode;
import backend.instructions.STR.StrMode;
import backend.instructions.addressing.*;
import backend.instructions.arithmeticLogic.*;
import backend.instructions.memory.Pop;
import backend.instructions.memory.Push;
import backend.instructions.operand.*;
import static utils.backend.register.arm.ARMConcreteRegister.*;
import backend.Instruction;
import backend.InstructionGenerator;
import backend.arm.instructions.*;
import backend.arm.instructions.LDR.LdrMode;
import backend.arm.instructions.STR.StrMode;
import backend.arm.instructions.addressing.*;
import backend.arm.instructions.arithmeticLogic.*;
import backend.arm.instructions.Pop;
import backend.arm.instructions.Push;
import backend.common.address.Address;
import frontend.node.*;
import frontend.node.expr.*;
import frontend.node.expr.BinopNode.Binop;
......@@ -39,14 +41,15 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import utils.NodeVisitor;
import utils.backend.LabelGenerator;
import utils.backend.register.ARMConcreteRegister;
import utils.backend.register.ARMConcreteRegisterAllocator;
import utils.backend.register.arm.ARMConcreteRegister;
import utils.backend.register.arm.ARMConcreteRegisterAllocator;
import utils.backend.register.Register;
import utils.frontend.symbolTable.SymbolTable;
public class ARMInstructionGenerator implements NodeVisitor<Void> {
public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction> {
/* maximum of bytes that can be added/subtracted from the stack pointer */
public static int MAX_STACK_STEP = (1 << 10);
......@@ -55,33 +58,18 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
/* the ARM concrete register allocator */
private final ARMConcreteRegisterAllocator armRegAllocator;
/* the code section of the assembly code */
private final List<Instruction> instructions;
/* the .data section of the assembly code */
private final Map<Label, String> dataSegmentMessages;
/* call getLabel() on branchLabelGenerator to get label in the format of "L0, L1, L2, ..." */
private final LabelGenerator branchLabelGenerator;
/* call getLabel() on msgLabelGenerator to get label in the format of "msg_0, msg_1, msg_2, ..."*/
private final LabelGenerator msgLabelGenerator;
protected final Map<Label, String> dataSegmentMessages;
/* a list of instructions for storing different helper functions
* would be appended to the end of instructions list while printing */
private final List<Instruction> ARMRoutines;
private final List<ARMInstruction> ARMRoutines;
/* record which helpers already exist, we don't want repeated helper functions */
private final Set<RoutineInstruction> alreadyExist;
/* record the current symbolTable used during instruction generation */
private SymbolTable currSymbolTable;
/* record the symbolTable of the innermost loop */
private SymbolTable currForLoopSymbolTable;
/* mark if we are visiting a lhs or rhs of an expr */
private boolean isLhs;
/* offset used when pushing variable in stack in visitFunctionCall
* USED FOR evaluating function parameters, not for changing parameters' offset in function body*/
private int stackOffset;
/* used by visitFunc and visitReturn, set how many byte this function used on stack
accumulated, on enter a new scope, decrease on exit
no need to distinguish function and non function scope, as non function scope does not call return */
private int funcStackSize;
/* call getLabel() on branchLabelGenerator to get label in the format of "L0, L1, L2, ..." */
protected final LabelGenerator<Label> branchLabelGenerator;
/* call getLabel() on msgLabelGenerator to get label in the format of "msg_0, msg_1, msg_2, ..."*/
protected final LabelGenerator<Label> msgLabelGenerator;
/* used when a break/jump occure in a loop statment, accumulated on entering scope */
private int loopStackSize;
......@@ -99,19 +87,13 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
private Label currContinueJumpToLabel;
public ARMInstructionGenerator() {
super();
armRegAllocator = new ARMConcreteRegisterAllocator();
instructions = new ArrayList<>();
dataSegmentMessages = new LinkedHashMap<>();
currSymbolTable = null;
branchLabelGenerator = new LabelGenerator(BRANCH_HEADER);
msgLabelGenerator = new LabelGenerator(MSG_HEADER);
stackOffset = 0;
ARMRoutines = new ArrayList<>();
alreadyExist = new HashSet<>();
isLhs = false;
currBreakJumpToLabel = null;
currContinueJumpToLabel = null;
currForLoopSymbolTable = null;
branchLabelGenerator = new LabelGenerator<Label>(BRANCH_HEADER, Label.class);
msgLabelGenerator = new LabelGenerator<>(MSG_HEADER, Label.class);
dataSegmentMessages = new LinkedHashMap<>();
}
@Override
......@@ -146,12 +128,12 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
/* if the struct is not initialised (null) */
if (!node.isInitialised()) {
ARMConcreteRegister reg = armRegAllocator.allocate();
instructions.add(new LDR(reg, new ImmediateAddressing(0)));
instructions.add(new LDR(reg, new ImmedAddress(0)));
return null;
}
/* load R0 with the number of bytes needed and malloc */
instructions.add(new LDR(r0, new ImmediateAddressing(node.getSize())));
instructions.add(new LDR(r0, new ImmedAddress(node.getSize())));
instructions.add(new BL(MALLOC.toString()));
/* then MOV the result pointer of the struct to the next available register */
......@@ -199,7 +181,7 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
} else {
indexReg = armRegAllocator.allocate();
instructions
.add(new LDR(indexReg, new ImmediateAddressing(((IntegerNode) index).getVal())));
.add(new LDR(indexReg, new ImmedAddress(((IntegerNode) index).getVal())));
}
/* check array bound */
......@@ -208,7 +190,7 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
instructions.add(new Mov(r1, new Operand2(addrReg)));
instructions.add(new BL(CHECK_ARRAY_BOUND.toString()));
instructions.add(new Add(addrReg, addrReg, new Operand2(POINTER_SIZE)));
instructions.add(new Add(addrReg, addrReg, new Operand2(ARM_POINTER_SIZE)));
int elemSize = i < node.getDepth() - 1 ? 2 : node.getType().getSize() / 2;
instructions.add(new Add(addrReg, addrReg, new Operand2(indexReg, LSL, elemSize)));
......@@ -230,10 +212,10 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
/* get the total number of bytes needed to allocate enough space for the array */
int size = node.getType() == null ? 0 : node.getContentSize() * node.getLength();
/* add 4 bytes to `size` to include the size of the array as the first byte */
size += POINTER_SIZE;
size += ARM_POINTER_SIZE;
/* load R0 with the number of bytes needed and malloc */
instructions.add(new LDR(r0, new ImmediateAddressing(size)));
instructions.add(new LDR(r0, new ImmedAddress(size)));
instructions.add(new BL(MALLOC.toString()));
/* then MOV the result pointer of the array to the next available register */
......@@ -254,7 +236,7 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
Register sizeReg = armRegAllocator.allocate();
/* STR the size of the array in the first byte */
instructions.add(new LDR(sizeReg, new ImmediateAddressing(node.getLength())));
instructions.add(new LDR(sizeReg, new ImmedAddress(node.getLength())));
instructions.add(new STR(sizeReg, new AddressingMode2(OFFSET, addrReg)));
armRegAllocator.free();
......@@ -284,10 +266,10 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
Binop operator = node.getOperator();
Operand2 op2 = new Operand2(e2reg);
List<Instruction> insList = ArithmeticLogic.binopInstruction
List<Instruction> insList = ARMArithmeticLogic.binopInstruction
.get(operator)
.binopAssemble(e1reg, e1reg, op2, operator);
instructions.addAll(insList);
instructions.addAll(insList.stream().map(i -> (ARMInstruction) i).collect(Collectors.toList()));
if (operator == Binop.DIV || operator == Binop.MOD) {
checkAndAddRoutine(CHECK_DIVIDE_BY_ZERO, msgLabelGenerator, dataSegmentMessages);
}
......@@ -323,7 +305,7 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
@Override
public Void visitCharNode(CharNode node) {
ARMConcreteRegister reg = armRegAllocator.allocate();
Immediate immed = new Immediate(node.getAsciiValue(), CONST8, true);
ARMImmediate immed = new ARMImmediate(node.getAsciiValue(), CONST8, true);
instructions.add(new Mov(reg, new Operand2(immed)));
return null;
}
......@@ -331,7 +313,7 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
@Override
public Void visitIntegerNode(IntegerNode node) {
ARMConcreteRegister reg = armRegAllocator.allocate();
instructions.add(new LDR(reg, new ImmediateAddressing(node.getVal())));
instructions.add(new LDR(reg, new ImmedAddress(node.getVal())));
return null;
}
......@@ -348,8 +330,8 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
for (int i = paramNum - 1; i >= 0; i--) {
ExprNode expr = params.get(i);
Register reg = armRegAllocator.next();
visit(expr);
Register reg = armRegAllocator.curr();
int size = expr.getType().getSize();
StrMode mode = size > 1 ? STR : STRB;
instructions.add(new STR(reg, new AddressingMode2(PREINDEX, SP, -size), mode));
......@@ -370,7 +352,7 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
instructions.add(new Add(SP, SP, new Operand2(paramSize)));
}
/* 4 get result, put in register */
/* 4 get result, put in a general register */
instructions.add(new Mov(armRegAllocator.allocate(), new Operand2(r0)));
return null;
......@@ -435,7 +417,7 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
if (node.isFirst()) {
addrMode = new AddressingMode2(OFFSET, reg);
} else {
addrMode = new AddressingMode2(OFFSET, reg, POINTER_SIZE);
addrMode = new AddressingMode2(OFFSET, reg, ARM_POINTER_SIZE);
}
if (isLhs) {
......@@ -453,14 +435,14 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
/* null is also a pairNode
* if one of child is null, the other has to be null */
if (node.getFst() == null || node.getSnd() == null) {
instructions.add(new LDR(armRegAllocator.allocate(), new ImmediateAddressing(0)));
instructions.add(new LDR(armRegAllocator.allocate(), new ImmedAddress(0)));
return null;
}
/* 1 malloc pair */
/* 1.1 move size of a pair in r0
* pair in heap is 2 pointers, so 8 byte */
instructions.add(new LDR(r0, new ImmediateAddressing(2 * POINTER_SIZE)));
instructions.add(new LDR(r0, new ImmedAddress(2 * ARM_POINTER_SIZE)));
/* 1.2 BL malloc and get pointer in general use register*/
instructions.add(new BL(MALLOC.toString()));
......@@ -482,7 +464,7 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
visit(child);
/* 2 move size of fst child in r0 */
instructions.add(new LDR(r0, new ImmediateAddressing(child.getType().getSize())));
instructions.add(new LDR(r0, new ImmedAddress(child.getType().getSize())));
/* 3 BL malloc, assign child value and get pointer in heap area pairPointer[0] or [1] */
instructions.add(new BL(MALLOC.toString()));
......@@ -499,13 +481,13 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
public Void visitStringNode(StringNode node) {
/* Add msg into the data list */
String str = node.getString();
Label msgLabel = msgLabelGenerator.getLabel();
Label msgLabel = msgLabelGenerator.getLabel().asArmLabel();
dataSegmentMessages.put(msgLabel, str);
/* Add the instructions */
ARMConcreteRegister reg = armRegAllocator.allocate();
Addressing strLabel = new LabelAddressing(msgLabel);
Address strLabel = new ImmedAddress(msgLabel);
instructions.add(new LDR(reg, strLabel));
return null;
......@@ -517,10 +499,9 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
Register reg = armRegAllocator.curr();
Unop operator = node.getOperator();
List<Instruction> insList = unopInstruction
.get(operator)
.unopAssemble(reg, reg);
instructions.addAll(insList);
List<Instruction> insList = armUnopAsm
.unopAssemble(reg, reg, operator, null);
instructions.addAll(insList.stream().map(i -> (ARMInstruction) i).collect(