mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-16 07:28:52 +00:00
Change Option<DataSize> to DataSize
This commit is contained in:
107
src/asm/mod.rs
107
src/asm/mod.rs
@@ -168,31 +168,23 @@ pub enum Instruction {
|
|||||||
Pseudo(Pseudo),
|
Pseudo(Pseudo),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the enum variant contains `Option<DataSize>`,
|
|
||||||
/// it means that the instructions used may vary according to `DataSize`.
|
|
||||||
/// Use 'Some' if RISC-V ISA provides instruction to support a specific 'DataSize',
|
|
||||||
/// if not, 'None' which means to use default instruction.
|
|
||||||
/// Because KECC uses RV64 (RISC-V ISA for 64-bit architecture),
|
|
||||||
/// KECC uses `Some` if `DataSize` is `Word`, if not, use `None`.
|
|
||||||
/// https://riscv.org/specifications/isa-spec-pdf/ (35p)
|
|
||||||
///
|
|
||||||
/// If the enum variant contains `bool`,
|
/// If the enum variant contains `bool`,
|
||||||
/// It means that different instructions exist
|
/// It means that different instructions exist
|
||||||
/// depending on whether the operand is signed or not.
|
/// depending on whether the operand is signed or not.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum RType {
|
pub enum RType {
|
||||||
Add(Option<DataSize>),
|
Add(DataSize),
|
||||||
Sub(Option<DataSize>),
|
Sub(DataSize),
|
||||||
Sll(Option<DataSize>),
|
Sll(DataSize),
|
||||||
Srl(Option<DataSize>),
|
Srl(DataSize),
|
||||||
Sra(Option<DataSize>),
|
Sra(DataSize),
|
||||||
Mul(Option<DataSize>),
|
Mul(DataSize),
|
||||||
Div {
|
Div {
|
||||||
data_size: Option<DataSize>,
|
data_size: DataSize,
|
||||||
is_signed: bool,
|
is_signed: bool,
|
||||||
},
|
},
|
||||||
Rem {
|
Rem {
|
||||||
data_size: Option<DataSize>,
|
data_size: DataSize,
|
||||||
is_signed: bool,
|
is_signed: bool,
|
||||||
},
|
},
|
||||||
Slt {
|
Slt {
|
||||||
@@ -218,7 +210,7 @@ pub enum RType {
|
|||||||
/// fcvt.s.l(u) or fcvt.d.l(u)
|
/// fcvt.s.l(u) or fcvt.d.l(u)
|
||||||
/// fcvt.s.w(u) or fcvt.d.w(u)
|
/// fcvt.s.w(u) or fcvt.d.w(u)
|
||||||
FcvtIntToFloat {
|
FcvtIntToFloat {
|
||||||
int_data_size: Option<DataSize>,
|
int_data_size: DataSize,
|
||||||
float_data_size: DataSize,
|
float_data_size: DataSize,
|
||||||
is_signed: bool,
|
is_signed: bool,
|
||||||
},
|
},
|
||||||
@@ -226,7 +218,7 @@ pub enum RType {
|
|||||||
/// fcvt.w(u).s or fcvt.w(u).d
|
/// fcvt.w(u).s or fcvt.w(u).d
|
||||||
FcvtFloatToInt {
|
FcvtFloatToInt {
|
||||||
float_data_size: DataSize,
|
float_data_size: DataSize,
|
||||||
int_data_size: Option<DataSize>,
|
int_data_size: DataSize,
|
||||||
is_signed: bool,
|
is_signed: bool,
|
||||||
},
|
},
|
||||||
/// fcvt.s.d or fcvt.d.s
|
/// fcvt.s.d or fcvt.d.s
|
||||||
@@ -240,58 +232,58 @@ impl RType {
|
|||||||
pub fn add(dtype: ir::Dtype) -> Self {
|
pub fn add(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Add(data_size.word())
|
Self::Add(data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub(dtype: ir::Dtype) -> Self {
|
pub fn sub(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Sub(data_size.word())
|
Self::Sub(data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sll(dtype: ir::Dtype) -> Self {
|
pub fn sll(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Sll(data_size.word())
|
Self::Sll(data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn srl(dtype: ir::Dtype) -> Self {
|
pub fn srl(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Srl(data_size.word())
|
Self::Srl(data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sra(dtype: ir::Dtype) -> Self {
|
pub fn sra(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Sra(data_size.word())
|
Self::Sra(data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mul(dtype: ir::Dtype) -> Self {
|
pub fn mul(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Mul(data_size.word())
|
Self::Mul(data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn div(dtype: ir::Dtype, is_signed: bool) -> Self {
|
pub fn div(dtype: ir::Dtype, is_signed: bool) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Div {
|
Self::Div {
|
||||||
data_size: data_size.word(),
|
data_size,
|
||||||
is_signed,
|
is_signed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,10 +291,10 @@ impl RType {
|
|||||||
pub fn rem(dtype: ir::Dtype, is_signed: bool) -> Self {
|
pub fn rem(dtype: ir::Dtype, is_signed: bool) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Rem {
|
Self::Rem {
|
||||||
data_size: data_size.word(),
|
data_size,
|
||||||
is_signed,
|
is_signed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,14 +367,14 @@ impl RType {
|
|||||||
let is_signed = from.is_int_signed();
|
let is_signed = from.is_int_signed();
|
||||||
let int_data_size =
|
let int_data_size =
|
||||||
DataSize::try_from(from).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(from).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(int_data_size.is_integer());
|
assert!(matches!(int_data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
let float_data_size =
|
let float_data_size =
|
||||||
DataSize::try_from(to).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(to).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(float_data_size.is_floating_point());
|
assert!(float_data_size.is_floating_point());
|
||||||
|
|
||||||
Self::FcvtIntToFloat {
|
Self::FcvtIntToFloat {
|
||||||
int_data_size: int_data_size.word(),
|
int_data_size,
|
||||||
float_data_size,
|
float_data_size,
|
||||||
is_signed,
|
is_signed,
|
||||||
}
|
}
|
||||||
@@ -396,36 +388,29 @@ impl RType {
|
|||||||
let is_signed = to.is_int_signed();
|
let is_signed = to.is_int_signed();
|
||||||
let int_data_size =
|
let int_data_size =
|
||||||
DataSize::try_from(to).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(to).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(int_data_size.is_integer());
|
assert!(matches!(int_data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::FcvtFloatToInt {
|
Self::FcvtFloatToInt {
|
||||||
float_data_size,
|
float_data_size,
|
||||||
int_data_size: int_data_size.word(),
|
int_data_size,
|
||||||
is_signed,
|
is_signed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the enum variant contains `Option<DataSize>`,
|
|
||||||
/// it means that the instructions used may vary according to `DataSize`.
|
|
||||||
/// Use 'Some' if RISC-V ISA provides instruction to support a specific 'DataSize',
|
|
||||||
/// if not, 'None' which means to use default instruction.
|
|
||||||
/// Because KECC uses RV64 (RISC-V ISA for 64-bit architecture),
|
|
||||||
/// KECC uses `Some` if `DataSize` is `Word`, if not, use `None`.
|
|
||||||
/// https://riscv.org/specifications/isa-spec-pdf/ (35p)
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum IType {
|
pub enum IType {
|
||||||
Load {
|
Load {
|
||||||
data_size: DataSize,
|
data_size: DataSize,
|
||||||
is_signed: bool,
|
is_signed: bool,
|
||||||
},
|
},
|
||||||
Addi(Option<DataSize>),
|
Addi(DataSize),
|
||||||
Xori,
|
Xori,
|
||||||
Ori,
|
Ori,
|
||||||
Andi,
|
Andi,
|
||||||
Slli(Option<DataSize>),
|
Slli(DataSize),
|
||||||
Srli(Option<DataSize>),
|
Srli(DataSize),
|
||||||
Srai(Option<DataSize>),
|
Srai(DataSize),
|
||||||
Slti {
|
Slti {
|
||||||
is_signed: bool,
|
is_signed: bool,
|
||||||
},
|
},
|
||||||
@@ -440,7 +425,7 @@ impl IType {
|
|||||||
data_size: DataSize::Double,
|
data_size: DataSize::Double,
|
||||||
is_signed: true,
|
is_signed: true,
|
||||||
};
|
};
|
||||||
pub const ADDI: Self = Self::Addi(None);
|
pub const ADDI: Self = Self::Addi(DataSize::Double);
|
||||||
|
|
||||||
pub fn load(dtype: ir::Dtype) -> Self {
|
pub fn load(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
@@ -467,25 +452,25 @@ impl IType {
|
|||||||
pub fn slli(dtype: ir::Dtype) -> Self {
|
pub fn slli(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Slli(data_size.word())
|
Self::Slli(data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn srli(dtype: ir::Dtype) -> Self {
|
pub fn srli(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Srli(data_size.word())
|
Self::Srli(data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn srai(dtype: ir::Dtype) -> Self {
|
pub fn srai(dtype: ir::Dtype) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
assert!(data_size.is_integer());
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
|
|
||||||
Self::Srai(data_size.word())
|
Self::Srai(data_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,7 +528,7 @@ pub enum Pseudo {
|
|||||||
},
|
},
|
||||||
/// neg(w) rd, rs
|
/// neg(w) rd, rs
|
||||||
Neg {
|
Neg {
|
||||||
data_size: Option<DataSize>,
|
data_size: DataSize,
|
||||||
rd: Register,
|
rd: Register,
|
||||||
rs: Register,
|
rs: Register,
|
||||||
},
|
},
|
||||||
@@ -575,11 +560,7 @@ impl Pseudo {
|
|||||||
pub fn neg(dtype: ir::Dtype, rd: Register, rs: Register) -> Self {
|
pub fn neg(dtype: ir::Dtype, rd: Register, rs: Register) -> Self {
|
||||||
let data_size =
|
let data_size =
|
||||||
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
DataSize::try_from(dtype).expect("`data_size` must be derived from `dtype`");
|
||||||
let data_size = if data_size == DataSize::Word {
|
assert!(matches!(data_size, DataSize::Word | DataSize::Double));
|
||||||
Some(data_size)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
Self::Neg { data_size, rd, rs }
|
Self::Neg { data_size, rd, rs }
|
||||||
}
|
}
|
||||||
@@ -633,7 +614,7 @@ impl Label {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum DataSize {
|
pub enum DataSize {
|
||||||
Byte,
|
Byte,
|
||||||
Half,
|
Half,
|
||||||
|
|||||||
@@ -205,19 +205,19 @@ impl WriteString for Instruction {
|
|||||||
impl WriteString for RType {
|
impl WriteString for RType {
|
||||||
fn write_string(&self) -> String {
|
fn write_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::Add(data_size) => format!("add{}", data_size.write_string()),
|
Self::Add(data_size) => format!("add{}", data_size.word().write_string()),
|
||||||
Self::Sub(data_size) => format!("sub{}", data_size.write_string()),
|
Self::Sub(data_size) => format!("sub{}", data_size.word().write_string()),
|
||||||
Self::Sll(data_size) => format!("sll{}", data_size.write_string()),
|
Self::Sll(data_size) => format!("sll{}", data_size.word().write_string()),
|
||||||
Self::Srl(data_size) => format!("srl{}", data_size.write_string()),
|
Self::Srl(data_size) => format!("srl{}", data_size.word().write_string()),
|
||||||
Self::Sra(data_size) => format!("sra{}", data_size.write_string()),
|
Self::Sra(data_size) => format!("sra{}", data_size.word().write_string()),
|
||||||
Self::Mul(data_size) => format!("mul{}", data_size.write_string()),
|
Self::Mul(data_size) => format!("mul{}", data_size.word().write_string()),
|
||||||
Self::Div {
|
Self::Div {
|
||||||
data_size,
|
data_size,
|
||||||
is_signed,
|
is_signed,
|
||||||
} => format!(
|
} => format!(
|
||||||
"div{}{}",
|
"div{}{}",
|
||||||
if *is_signed { "" } else { "u" },
|
if *is_signed { "" } else { "u" },
|
||||||
data_size.write_string()
|
data_size.word().write_string()
|
||||||
),
|
),
|
||||||
Self::Rem {
|
Self::Rem {
|
||||||
data_size,
|
data_size,
|
||||||
@@ -225,7 +225,7 @@ impl WriteString for RType {
|
|||||||
} => format!(
|
} => format!(
|
||||||
"rem{}{}",
|
"rem{}{}",
|
||||||
if *is_signed { "" } else { "u" },
|
if *is_signed { "" } else { "u" },
|
||||||
data_size.write_string()
|
data_size.word().write_string()
|
||||||
),
|
),
|
||||||
Self::Slt { is_signed } => format!("slt{}", if *is_signed { "" } else { "u" }),
|
Self::Slt { is_signed } => format!("slt{}", if *is_signed { "" } else { "u" }),
|
||||||
Self::Xor => "xor".to_string(),
|
Self::Xor => "xor".to_string(),
|
||||||
@@ -265,10 +265,10 @@ impl WriteString for RType {
|
|||||||
is_signed,
|
is_signed,
|
||||||
} => {
|
} => {
|
||||||
assert!(float_data_size.is_floating_point());
|
assert!(float_data_size.is_floating_point());
|
||||||
|
assert!(matches!(int_data_size, DataSize::Word | DataSize::Double));
|
||||||
format!(
|
format!(
|
||||||
"fcvt.{}{}.{}",
|
"fcvt.{}{}.{}",
|
||||||
if let Some(int_data_size) = int_data_size {
|
if matches!(int_data_size, DataSize::Word) {
|
||||||
assert_eq!(*int_data_size, DataSize::Word);
|
|
||||||
"w"
|
"w"
|
||||||
} else {
|
} else {
|
||||||
"l"
|
"l"
|
||||||
@@ -284,11 +284,11 @@ impl WriteString for RType {
|
|||||||
is_signed,
|
is_signed,
|
||||||
} => {
|
} => {
|
||||||
assert!(float_data_size.is_floating_point());
|
assert!(float_data_size.is_floating_point());
|
||||||
|
assert!(matches!(int_data_size, DataSize::Word | DataSize::Double));
|
||||||
format!(
|
format!(
|
||||||
"fcvt.{}.{}{}",
|
"fcvt.{}.{}{}",
|
||||||
float_data_size.write_string(),
|
float_data_size.write_string(),
|
||||||
if let Some(int_data_size) = int_data_size {
|
if matches!(int_data_size, DataSize::Word) {
|
||||||
assert_eq!(*int_data_size, DataSize::Word);
|
|
||||||
"w"
|
"w"
|
||||||
} else {
|
} else {
|
||||||
"l"
|
"l"
|
||||||
@@ -330,13 +330,13 @@ impl WriteString for IType {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Addi(data_size) => format!("addi{}", data_size.write_string()),
|
Self::Addi(data_size) => format!("addi{}", data_size.word().write_string()),
|
||||||
Self::Xori => "xori".to_string(),
|
Self::Xori => "xori".to_string(),
|
||||||
Self::Ori => "ori".to_string(),
|
Self::Ori => "ori".to_string(),
|
||||||
Self::Andi => "andi".to_string(),
|
Self::Andi => "andi".to_string(),
|
||||||
Self::Slli(data_size) => format!("slli{}", data_size.write_string()),
|
Self::Slli(data_size) => format!("slli{}", data_size.word().write_string()),
|
||||||
Self::Srli(data_size) => format!("srli{}", data_size.write_string()),
|
Self::Srli(data_size) => format!("srli{}", data_size.word().write_string()),
|
||||||
Self::Srai(data_size) => format!("srai{}", data_size.write_string()),
|
Self::Srai(data_size) => format!("srai{}", data_size.word().write_string()),
|
||||||
Self::Slti { is_signed } => format!("slti{}", if *is_signed { "" } else { "u" }),
|
Self::Slti { is_signed } => format!("slti{}", if *is_signed { "" } else { "u" }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,7 +396,7 @@ impl WriteString for Pseudo {
|
|||||||
),
|
),
|
||||||
Self::Neg { data_size, rd, rs } => format!(
|
Self::Neg { data_size, rd, rs } => format!(
|
||||||
"neg{}\t{},{}",
|
"neg{}\t{},{}",
|
||||||
data_size.write_string(),
|
data_size.word().write_string(),
|
||||||
rd.write_string(),
|
rd.write_string(),
|
||||||
rs.write_string()
|
rs.write_string()
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user