Files
WACC_37/src/main/wacc/backend/assemblyIR.scala
2025-02-16 17:58:35 +00:00

98 lines
2.8 KiB
Scala

package wacc
object assemblyIR {
sealed trait Operand
// did not use option because we'd have to wrap each op around Some(). can refactor
case object NoOperand extends Operand {
override def toString = ""
}
sealed trait Src extends Operand // mem location, register and imm value
sealed trait Dest extends Operand // mem location and register
enum RegSize {
case R64
case E32
override def toString = this match {
case R64 => "r"
case E32 => "e"
}
}
//arguments
enum CLibFunc extends Operand {
case Scanf,
Puts,
Fflush,
Exit,
PrintF
private val plt = "@plt"
override def toString = this match {
case Scanf => "scanf" + plt
case Puts => "puts" + plt
case Fflush => "fflush" + plt
case Exit => "exit" + plt
case PrintF => "printf" + plt
}
}
enum Register extends Dest with Src {
case Named(name: String, size: RegSize)
case Scratch(num: Int, size: RegSize)
override def toString = this match {
case Named(name, size) => s"${size}${name.toLowerCase()}"
case Scratch(num, size) => s"${size}${num}"
}
}
case class MemLocation(pointer: Long | Register) extends Dest with Src {
override def toString = pointer match {
case hex: Long => f"[0x$hex%X]"
case reg: Register => s"[$reg]"
}
}
case class ImmediateVal(value: Int) extends Src {
override def toString = s"#${value.toString}"
}
case class LabelArg(name: String) extends Operand {
override def toString = name
}
//TODO Check if dest and src are not both memory locations
abstract class Operation(ins: String, op1: Operand = NoOperand, op2: Operand = NoOperand) {
override def toString: String = if (op2 == NoOperand) {
s"$ins ${op1.toString}"
} else {
s"$ins ${op1.toString}, ${op2.toString}"
}
}
case class Add(op1: Dest, op2: Src) extends Operation("add", op1, op2)
case class Subtract(op1: Dest, op2: Src) extends Operation("sub", op1, op2)
case class Multiply(op1: Src) extends Operation("mul", op1)
case class Divide(op1: Src) extends Operation("div", op1)
case class And(op1: Dest, op2: Src) extends Operation("and", op1, op2)
case class Or(op1: Dest, op2: Src) extends Operation("or", op1, op2)
case class Compare(op1: Dest, op2: Src) extends Operation("cmp", op1, op2)
//stack operations
case class Push(op1: Src) extends Operation("push", op1)
case class Pop(op1: Src) extends Operation("pop", op1)
case class Call(op1: CLibFunc) extends Operation("call", op1)
case class Return() extends Operation("ret")
case class Jump(op1: LabelArg) extends Operation("jmp", op1)
case class JumpIfEqual(op1: LabelArg) extends Operation("je", op1)
case class LabelDef(name: String) {
override def toString = s"$name:"
}
}