Commit 027be18b authored by 徐世桐's avatar 徐世桐
Browse files

Merge branch 'wacc-intel-function'

parents 1f231be0 54358b75
......@@ -25,11 +25,9 @@ for folder in ${VALID_EXAMPLES[@]}; do
echo $file
./compile -t -o1 $file > "${EXECUTABLE_FILE_NAME}.log.txt"
mv "${EXECUTABLE_FILE_NAME}.log.txt" "${VALID_EXAMPLES_SRC_DIR}${folder}/${FILE_NAME}.log"
# if diff "${EXECUTABLE_FILE_NAME}.log.txt" "${VALID_EXAMPLES_SRC_DIR}${folder}/${FILE_NAME}.log" -I scope; then
# (( COUNTER += 1 ))
# fi
if diff "${EXECUTABLE_FILE_NAME}.log.txt" "${VALID_EXAMPLES_SRC_DIR}${folder}/${FILE_NAME}.log" -I scope; then
(( COUNTER += 1 ))
fi
echo "$COUNTER / $(($TOTAL_COUNT)) files have been executed"
......
......@@ -2,13 +2,13 @@
VALID_EXAMPLES=(
#"/advanced"
#"/array"
"/array"
"/basic"
"/expressions"
#"/function"
"/function"
"/if"
"/IO"
#"/pairs"
"/pairs"
#"/runtimeErr"
"/scope"
"/sequence"
......
......@@ -268,7 +268,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
List<Instruction> insList = ARMArithmeticLogic.binopInstruction
.get(operator)
.binopAssemble(e1reg, e1reg, op2, operator);
.binopAssemble(e1reg, e2reg, op2, operator);
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);
......
......@@ -11,47 +11,60 @@ public class Operand2 extends Address {
private final ARMImmediate immed;
private final Operand2Operator operator;
private final Register Rm;
private Operand2(Register Rm, Operand2Operator operator, ARMImmediate immed) {
private final Register Rs;
private Operand2(Register Rm, Register Rs, Operand2Operator operator, ARMImmediate immed) {
this.immed = immed;
this.operator = operator;
this.Rm = Rm;
this.Rs = Rs;
}
public Operand2(Register Rm, Operand2Operator operator, int intVal) {
this.immed = new ARMImmediate(intVal, BitNum.CONST5);
this.operator = operator;
this.Rm = Rm;
this.Rs = null;
}
public Operand2(ARMImmediate immed) {
this(null, Operand2Operator.NONE, immed);
this(null, null, Operand2Operator.NONE, immed);
}
public Operand2(int intVal) {
this(null, Operand2Operator.NONE, new ARMImmediate(intVal, BitNum.CONST8));
this(null, null, Operand2Operator.NONE, new ARMImmediate(intVal, BitNum.CONST8));
}
public Operand2(Register Rm) {
this(Rm, Operand2Operator.NONE, null);
this(Rm, null, Operand2Operator.NONE, null);
}
public Operand2(Register Rm, Operand2Operator operator) {
this(Rm, operator, null);
this(Rm, null, operator, null);
}
public Operand2(Register Rm, Register Rs, Operand2Operator operator) {
this(Rm, Rs, operator, null);
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
if (Rm != null) {
res.append(Rm.toString());
}
if (Rm != null) {
res.append(Rm.toString());
}
if (Rs != null) {
res.append(", ").append(operator).append(" ").append(Rs);
} else {
if (operator != Operand2Operator.NONE) {
res.append(", " + operator.toString() + " ");
res.append(", " + operator + " ");
}
if (immed != null) {
res.append(immed.toString());
res.append(immed.toString());
}
}
return res.toString();
}
......
......@@ -12,6 +12,7 @@ import backend.arm.instructions.addressing.AddressingMode2.AddrMode2;
import backend.arm.instructions.addressing.ARMImmediate;
import backend.arm.instructions.addressing.ARMImmediate.BitNum;
import backend.arm.instructions.addressing.Operand2;
import backend.arm.instructions.addressing.Operand2.Operand2Operator;
import backend.common.address.Address;
import backend.common.arithmeticLogic.ArithmeticLogic;
import backend.common.arithmeticLogic.BinopAssemble;
......@@ -33,13 +34,16 @@ public abstract class ARMArithmeticLogic extends ArithmeticLogic implements ARMI
public static final BinopAssemble BasicBinopAsm = (rd, rn, op2, b) -> {
Map<Binop, ARMInstruction> m = Map.of(
Binop.PLUS, new Add(rd, rn, op2, Cond.S),
Binop.MINUS, new Sub(rd, rn, op2, Cond.S),
Binop.MUL, new SMull(rd, rn, op2),
Binop.AND, new And(rd, rn, op2),
Binop.OR, new Or(rd, rn, op2),
Binop.BITAND, new And(rd, rn, op2),
Binop.BITOR, new Or(rd, rn, op2)
Binop.PLUS, new Add(rd, rd, op2, Cond.S),
Binop.MINUS, new Sub(rd, rd, op2, Cond.S),
Binop.MUL, new SMull(rd, rd, op2),
Binop.AND, new And(rd, rd, op2),
Binop.OR, new Or(rd, rd, op2),
Binop.BITAND, new And(rd, rd, op2),
Binop.BITOR, new Or(rd, rd, op2),
Binop.BITXOR, new Eor(rd, rd, op2),
Binop.BITSHL, new Mov(rd, new Operand2(rd, rn, Operand2Operator.LSL)),
Binop.BITSHR, new Mov(rd, new Operand2(rd, rn, Operand2Operator.ASR))
);
return List.of(m.get(b));
};
......@@ -82,21 +86,24 @@ public abstract class ARMArithmeticLogic extends ArithmeticLogic implements ARMI
};
public static final Map<Binop, BinopAssemble> binopInstruction = Map.ofEntries(
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.PLUS, BasicBinopAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.MINUS, BasicBinopAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.MUL, BasicBinopAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.AND, BasicBinopAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.OR, BasicBinopAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.BITAND, BasicBinopAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.BITOR, BasicBinopAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.DIV, DivModAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.MOD, DivModAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.GREATER, CmpAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.GREATER_EQUAL, CmpAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.LESS, CmpAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.LESS_EQUAL, CmpAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.EQUAL, CmpAsm),
new AbstractMap.SimpleEntry<Binop, BinopAssemble>(Binop.INEQUAL, CmpAsm)
new AbstractMap.SimpleEntry<>(Binop.PLUS, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.MINUS, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.MUL, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.AND, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.OR, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.BITAND, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.BITOR, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.BITXOR, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.BITSHL, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.BITSHR, BasicBinopAsm),
new AbstractMap.SimpleEntry<>(Binop.DIV, DivModAsm),
new AbstractMap.SimpleEntry<>(Binop.MOD, DivModAsm),
new AbstractMap.SimpleEntry<>(Binop.GREATER, CmpAsm),
new AbstractMap.SimpleEntry<>(Binop.GREATER_EQUAL, CmpAsm),
new AbstractMap.SimpleEntry<>(Binop.LESS, CmpAsm),
new AbstractMap.SimpleEntry<>(Binop.LESS_EQUAL, CmpAsm),
new AbstractMap.SimpleEntry<>(Binop.EQUAL, CmpAsm),
new AbstractMap.SimpleEntry<>(Binop.INEQUAL, CmpAsm)
);
public static final UnopAssemble armUnopAsm = (rd, rn, op, notUsed) -> {
......@@ -105,27 +112,13 @@ public abstract class ARMArithmeticLogic extends ArithmeticLogic implements ARMI
Unop.CHR, List.of(),
Unop.MINUS, List.of(new Rsb(rd, rn, new Operand2(new ARMImmediate(0, BitNum.CONST8)))),
Unop.NOT, List.of(new Xor(rd, rn, new Operand2(new ARMImmediate(1, BitNum.CONST8)))),
Unop.ORD, List.of()
Unop.ORD, List.of(),
Unop.BITNOT, List.of(new Mov(rd, new Operand2(rn), ARMMovType.MVN), new And(rd, rd, new Operand2(rn)))
);
return m.get(op);
};
public static UnopAssemble ComplementAsm = (rd, rn, op, notUsed) -> {
List<Instruction> list = new ArrayList<>();
list.add(new Mov(rd, new Operand2(rn), ARMMovType.MVN));
return list;
};
public static final Map<Unop, UnopAssemble> unopInstruction = Map.ofEntries(
new AbstractMap.SimpleEntry<Unop, UnopAssemble>(Unop.LEN, armUnopAsm),
new AbstractMap.SimpleEntry<Unop, UnopAssemble>(Unop.MINUS, armUnopAsm),
new AbstractMap.SimpleEntry<Unop, UnopAssemble>(Unop.NOT, armUnopAsm),
new AbstractMap.SimpleEntry<Unop, UnopAssemble>(Unop.ORD, armUnopAsm),
new AbstractMap.SimpleEntry<Unop, UnopAssemble>(Unop.CHR, armUnopAsm),
new AbstractMap.SimpleEntry<Unop, UnopAssemble>(Unop.COMPLEMENT, ComplementAsm)
);
protected ARMArithmeticLogic(Register rd, Register rn, Address operand2) {
super(rd, rn, operand2);
}
......
package backend.arm.instructions.arithmeticLogic;
import backend.arm.instructions.addressing.AddressingMode2;
import backend.arm.instructions.addressing.Operand2;
import backend.common.address.Address;
import utils.backend.Cond;
......
package backend.arm.instructions.arithmeticLogic;
import backend.common.address.Address;
import utils.backend.register.Register;
public class Eor extends ARMArithmeticLogic {
/* ORR{cond}{S} <Rd>, <Rn>, <operand2> */
public Eor(Register rd, Register rn, Address operand2) {
super(rd, rn, operand2);
}
@Override
public String assemble() {
return "EOR " + rd + ", " + rn + ", " + addr;
}
}
......@@ -3,13 +3,6 @@ package backend.intel;
import backend.Instruction;
import backend.InstructionGenerator;
import backend.arm.instructions.BL;
import backend.arm.instructions.LDR;
import backend.arm.instructions.STR;
import backend.arm.instructions.STR.StrMode;
import backend.arm.instructions.addressing.AddressingMode2;
import backend.arm.instructions.addressing.ImmedAddress;
import backend.arm.instructions.addressing.Operand2;
import backend.intel.instructions.*;
import backend.intel.instructions.Mov.IntelMovType;
import backend.intel.instructions.address.IntelAddress;
......@@ -56,7 +49,6 @@ import frontend.node.stat.StatNode;
import frontend.node.stat.SwitchNode;
import frontend.node.stat.WhileNode;
import frontend.type.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
......@@ -68,33 +60,10 @@ import utils.backend.register.Register;
import utils.backend.register.intel.IntelConcreteRegister;
import utils.backend.register.intel.IntelConcreteRegisterAllocator;
import static backend.arm.instructions.LDR.LdrMode.LDRSB;
import static backend.arm.instructions.STR.StrMode.STR;
import static backend.arm.instructions.STR.StrMode.STRB;
import static backend.arm.instructions.addressing.AddressingMode2.AddrMode2.OFFSET;
import static backend.arm.instructions.addressing.AddressingMode2.AddrMode2.PREINDEX;
import static backend.arm.instructions.arithmeticLogic.ARMArithmeticLogic.armUnopAsm;
import static utils.Utils.ARM_POINTER_SIZE;
import static utils.Utils.BOOL_BASIC_TYPE;
import static utils.Utils.CHAR_ARRAY_TYPE;
import static utils.Utils.CHAR_BASIC_TYPE;
import static utils.Utils.FALSE;
import static utils.Utils.FUNC_HEADER;
import static utils.Utils.INTEL_POINTER_SIZE;
import static utils.Utils.INT_BASIC_TYPE;
import static utils.Utils.RoutineInstruction.CHECK_NULL_POINTER;
import static utils.Utils.STRING_BASIC_TYPE;
import static utils.Utils.SystemCallInstruction.MALLOC;
import static utils.Utils.TRUE;
import static utils.Utils.WORD_SIZE;
import static utils.Utils.intToIntelSize;
import static utils.Utils.*;
import static utils.backend.Cond.E;
import static utils.backend.Cond.EQ;
import static utils.backend.Cond.NE;
import static utils.backend.Cond.NULL;
import static utils.backend.register.arm.ARMConcreteRegister.PC;
import static utils.backend.register.arm.ARMConcreteRegister.SP;
import static utils.backend.register.arm.ARMConcreteRegister.r0;
import static utils.backend.register.intel.IntelConcreteRegister.*;
public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruction> {
......@@ -112,6 +81,13 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
private int currParamListSize;
/* mark whether this scope is function top level scope
* Level -1: not in function
* Level 0: set by funcNode
* Level 1: function top level
* Level 2+: not function top level */
int funcLevel;
public IntelInstructionGenerator() {
branchLabelGenerator = new LabelGenerator<>(".L", Label.class);
dataLabelGenerator = new LabelGenerator<>(".LC", Label.class);
......@@ -119,6 +95,7 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
dataSection = new LinkedHashMap<>();
biDataSection = new LinkedHashMap<>();
currParamListSize = 0;
funcLevel = 0;
}
@Override
......@@ -126,8 +103,7 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
/* get the address of this array and store it in an available register */
IntelConcreteRegister addrReg = intelRegAllocator.allocate();
int offset = currSymbolTable.getStackOffset(node.getName(), node.getSymbol())
+ stackOffset;
int offset = currSymbolTable.getStackOffset(node.getName(), node.getSymbol());
instructions.add(new Mov(new IntelAddress(rbp, -offset), addrReg));
IntelConcreteRegister indexReg;
......@@ -145,7 +121,7 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
instructions.add(new Mov(new IntelAddress(((IntegerNode) index).getVal()), indexReg));
}
int elemSize = i < node.getDepth() - 1 ? 3 : node.getType().getSize() / 2;
int elemSize = i < node.getDepth() - 1 ? 3 : (int) (Math.log(node.getType().getSize()) / Math.log(2));
instructions.add(new Sal(elemSize, IntelInstructionSize.Q, indexReg));
instructions.add(new Add(indexReg, addrReg));
if (i < node.getDepth() - 1) instructions.add(new Mov(new IntelAddress(addrReg), addrReg));
......@@ -263,34 +239,32 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
*/
List<ExprNode> params = node.getParams();
int paramSize = 0;
stackOffset = 0;
int paramNum = params.size();
/* assign rbp as rsp, so that new parameters added will not overwrite variables */
// todo: 1 mov should be consistent with moved in parameter size,
// 2 should move to stack below rsp, prevent overwrite variable in using by main body
System.out.println("in function call");
for (int i = paramNum - 1; i >= 0; i--) {
ExprNode expr = params.get(i);
visit(expr);
IntelConcreteRegister reg = intelRegAllocator.curr();
int size = expr.getType().getSize();
instructions.add(new Sub(size, IntelInstructionSize.Q, rbp));
instructions.add(new Mov(reg.withSize(intToIntelSize.get(size)), new IntelAddress(rbp)));
instructions.add(new Sub(size, IntelInstructionSize.Q, rsp));
instructions.add(new Mov(reg.withSize(intToIntelSize.get(size)), new IntelAddress(rsp)));
intelRegAllocator.free();
paramSize += size;
stackOffset += size;
}
stackOffset = 0;
/* 2 call function with B instruction */
instructions.add(new Call(FUNC_HEADER + node.getFunction().getFunctionName()));
/* 3 add back stack pointer */
if (paramSize > 0) {
instructions.add(new Add(paramSize, IntelInstructionSize.Q, rbp));
instructions.add(new Add(paramSize, IntelInstructionSize.Q, rsp));
}
/* 4 get result, put in a general register */
......@@ -306,10 +280,19 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
System.out.println("ident " + node.getName() + " has:");
System.out.println("offset " + currSymbolTable.getStackOffset(node.getName(), node.getSymbol()));
System.out.println("paramList size " + currParamListSize);
System.out.println("stack offset" + stackOffset);
System.out.println("ident size " + identTypeSize);
System.out.print("ident type ");
node.getType().showType();
System.out.println();
System.out.println();
int offset = currSymbolTable.getStackOffset(node.getName(), node.getSymbol())
- currParamListSize + stackOffset;
int offset;
if (funcLevel == 1) {
offset = currSymbolTable.getStackOffset(node.getName(), node.getSymbol())
- currParamListSize;
} else {
offset = currSymbolTable.getStackOffset(node.getName(), node.getSymbol());
}
/* if is lhs, then only put address in register */
if (isLhs) {
......@@ -467,7 +450,12 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
/* TODO: add intel move type here */
int offset = node.getScope().lookup(node.getIdentifier()).getStackOffset();
int offset;
if (funcLevel == 1) {
offset = node.getScope().lookup(node.getIdentifier()).getStackOffset() - currParamListSize;
} else {
offset = node.getScope().lookup(node.getIdentifier()).getStackOffset();
}
instructions.add(new Mov(intelRegAllocator.curr().withSize(intToIntelSize.get(identTypeSize)), new IntelAddress(rbp, -offset)));
intelRegAllocator.free();
......@@ -555,7 +543,7 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
private final Map<Type, String> printTypeStringMap = Map.of(
INT_BASIC_TYPE, "%d",
CHAR_BASIC_TYPE, "%c",
STRING_BASIC_TYPE, "%s",
STRING_BASIC_TYPE_INTEL, "%s",
CHAR_ARRAY_TYPE, "%s"
);
......@@ -565,7 +553,7 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
Type type = node.getExpr().getType();
String printTypeString = printTypeStringMap.get(type);
String printTypeString = printTypeStringMap.getOrDefault(type, "%p");
if (type.equals(BOOL_BASIC_TYPE)) {
Label trueMsgLabel = biDataSection.get("true");
......@@ -645,8 +633,10 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
@Override
public Void visitReturnNode(ReturnNode node) {
System.out.println("return with rsp + " + funcStackSize);
visit(node.getExpr());
instructions.add(new Mov(intelRegAllocator.curr(), rax));
IntelInstructionSize intelSize = intToIntelSize.get(node.getExpr().getType().getSize());
instructions.add(new Mov(intelRegAllocator.curr().withSize(intelSize), rax.withSize(intelSize)));
intelRegAllocator.free();
if (funcStackSize != 0) {
instructions.add(new Add(funcStackSize, IntelInstructionSize.Q, rsp));
......@@ -660,9 +650,24 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
public Void visitScopeNode(ScopeNode node) {
List<StatNode> list = node.getBody();
System.out.println("funcLevel = " + funcLevel);
/* 1 leave space for variables in stack */
int stackSize = node.getScope().getParentSymbolTable() == null
? 0 : node.getScope().getParentSymbolTable().getSize();
? 0 : node.getScope().getParentSymbolTable().getSize();
if (funcLevel == -1) {
/* not in function, no operation */
} else {
/* function level increase on enter a new scope */
funcLevel++;
}
if (funcLevel == 2) {
/* prev scope was top level scope of function */
stackSize = node.getScope().getParentSymbolTable().getSize() - currParamListSize;
}
int temp = stackSize;
while (temp > 0) {
int realStackSize = temp / 1024 >= 1 ? 1024 : temp;
......@@ -670,9 +675,6 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
temp = temp - realStackSize;
}
/* accumulate function stack size, in case this scope is a function scope and contain return */
funcStackSize += stackSize;
/* 2 visit statements
* set currentSymbolTable here, eliminate all other set symbol table in other statNode */
currSymbolTable = node.getScope();
......@@ -680,10 +682,7 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
visit(elem);
}
currSymbolTable = currSymbolTable.getParentSymbolTable();
/* decrease function stack size, as from this point stack is freed by the scope, not by return */
funcStackSize -= stackSize;
/* 3 restore stack */
temp = stackSize;
while (temp > 0) {
......@@ -692,6 +691,13 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
temp = temp - realStackSize;
}
if (funcLevel == -1) {
/* not in function, no operation */
} else {
/* function level decrease on exit a scope */
funcLevel--;
}
return null;
}
......@@ -765,8 +771,8 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
public Void visitFuncNode(FuncNode node) {
/* cannot call get stack size on function body, as that will return 0
* public field used here, so that on visit return statement, return can add stack back */
funcStackSize = node.getFunctionBody().getScope().getSize();
funcStackSize -= node.paramListStackSize();
funcStackSize = node.getFunctionBody().minStackRequired();
System.out.println("in function " + node.getFunctionName());
/* 1 add function label,
* PUSH {lr}
......@@ -783,8 +789,11 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
/* 3 visit function,
* RETURN are responsible for adding stack back
* no need to set back isFuncTopLevel, since next visitFunc will set as true again,
* visit program will set it false after all visitFunc
*/
currParamListSize = node.paramListStackSize();
funcLevel = 0;
visit(node.getFunctionBody());
currParamListSize = 0;
......@@ -801,6 +810,10 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
visitFuncNode(func);
}
/* clear fields associated with function visit */
funcLevel = -1;
currParamListSize = 0;
/* 2 start of main */
Label mainLabel = new Label("main");
instructions.add(mainLabel);
......@@ -808,12 +821,14 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
/* 3 PUSH rsp and MOV rsp to rbp */
instructions.add(new Push(Collections.singletonList(rbp)));
instructions.add(new Mov(rsp, rbp));
instructions.add(new Sub(Math.max(16, node.getBody().getScope().getSize()), IntelInstructionSize.Q, rsp));
int rspOffset = Math.max(16, node.getBody().minStackRequired());
System.out.println("#################rsp offset: " + node.getBody().minStackRequired());
instructions.add(new Sub(rspOffset, IntelInstructionSize.Q, rsp));
/* 4 main body */
visit(node.getBody());
instructions.add(new Add(Math.max(16, node.getBody().getScope().getSize()), IntelInstructionSize.Q, rsp));
instructions.add(new Add(rspOffset, IntelInstructionSize.Q, rsp));
/* 5 set return value and return */
instructions.add(new Mov(new IntelAddress(0), rax.withSize(IntelInstructionSize.L)));
// instructions.add(new Pop(rbp)); // delete by sx119: otherwise cannot pass functionSimple
......
......@@ -361,8 +361,8 @@ public class SemanticChecker extends WACCParserBaseVisitor<Node> {
/* ARM: initialise as -4 byte in order to leave space for PUSH {lr},
which takes up 4 bute on stack
intel: rbp is assigned after push, so all */
int tempStackAddr = this.arch.equals(AssemblyArchitecture.ARMv6) ? -WORD_SIZE : -QUAD_SIZE;
intel: one QUAD size is for PC, one QUAD size is for rbp pushed */
int tempStackAddr = this.arch.equals(AssemblyArchitecture.ARMv6) ? -WORD_SIZE : -2 * QUAD_SIZE;
List<IdentNode> params = funcNode.getParamList();
int paramNum = params.size();
......@@ -1258,6 +1258,9 @@ public class SemanticChecker extends WACCParserBaseVisitor<Node> {
@Override
public Node visitStringType(StringTypeContext ctx) {
if (arch.equals(AssemblyArchitecture.Intelx86)) {
return new TypeDeclareNode(STRING_BASIC_TYPE_INTEL);
}
return new TypeDeclareNode(STRING_BASIC_TYPE);
}
......
......@@ -18,7 +18,7 @@ public class BinopNode extends ExprNode {
public enum Binop {
PLUS, MINUS, MUL, DIV, MOD, GREATER, GREATER_EQUAL, LESS, LESS_EQUAL, EQUAL,
INEQUAL, AND, OR, BITAND, BITOR, BITXOR