|
|
@ -145,6 +145,7 @@ fn fix_name(name: &String) -> String {
|
|
|
|
.replace("-", "_")
|
|
|
|
.replace("-", "_")
|
|
|
|
.replace("*", "p")
|
|
|
|
.replace("*", "p")
|
|
|
|
.replace("<>", "void")
|
|
|
|
.replace("<>", "void")
|
|
|
|
|
|
|
|
.replace(".", "_")
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -223,9 +224,26 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
|
|
|
|
],
|
|
|
|
],
|
|
|
|
));
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for global in module.globals.clone() {
|
|
|
|
|
|
|
|
let name: String = fix_name(&global.name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for dec in global.decorations {
|
|
|
|
|
|
|
|
// Decorations have the format Location 0, or Builtin FragCoord
|
|
|
|
|
|
|
|
let dec = match dec {
|
|
|
|
|
|
|
|
crate::compiler::Decoration::Location(loc) => format!("Location {}", loc),
|
|
|
|
|
|
|
|
crate::compiler::Decoration::BuiltIn(builtin) => {
|
|
|
|
|
|
|
|
let builtin = match builtin {
|
|
|
|
|
|
|
|
crate::compiler::BuiltinDecoration::FragCoord => "FragCoord",
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
format!("BuiltIn {}", builtin)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
ops.push((None, vec!["OpDecorate".to_string(), name.clone(), dec]));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for global in module.globals.clone() {
|
|
|
|
for global in module.globals.clone() {
|
|
|
|
let name = fix_name(&global.name);
|
|
|
|
let name: String = fix_name(&global.name);
|
|
|
|
let _typ = global.typ;
|
|
|
|
let _typ = global.typ;
|
|
|
|
let storage_class = match global.storage_class {
|
|
|
|
let storage_class = match global.storage_class {
|
|
|
|
crate::compiler::StorageClass::Input => "Input",
|
|
|
|
crate::compiler::StorageClass::Input => "Input",
|
|
|
@ -248,19 +266,6 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
|
|
|
|
storage_class.to_string(),
|
|
|
|
storage_class.to_string(),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
));
|
|
|
|
));
|
|
|
|
for dec in global.decorations {
|
|
|
|
|
|
|
|
// Decorations have the format Location 0, or Builtin FragCoord
|
|
|
|
|
|
|
|
let dec = match dec {
|
|
|
|
|
|
|
|
crate::compiler::Decoration::Location(loc) => format!("Location {}", loc),
|
|
|
|
|
|
|
|
crate::compiler::Decoration::BuiltIn(builtin) => {
|
|
|
|
|
|
|
|
let builtin = match builtin {
|
|
|
|
|
|
|
|
crate::compiler::BuiltinDecoration::FragCoord => "FragCoord",
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
format!("BuiltIn {}", builtin)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
ops.push((None, vec!["OpDecorate".to_string(), name.clone(), dec]));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for fun in module.functions.clone() {
|
|
|
|
for fun in module.functions.clone() {
|
|
|
@ -337,6 +342,7 @@ fn compile_biop(
|
|
|
|
counter: &mut i32,
|
|
|
|
counter: &mut i32,
|
|
|
|
stack: &mut Vec<String>,
|
|
|
|
stack: &mut Vec<String>,
|
|
|
|
out: &mut Vec<(Option<String>, String)>,
|
|
|
|
out: &mut Vec<(Option<String>, String)>,
|
|
|
|
|
|
|
|
typ: &str,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
assert!(lst.len() == 2);
|
|
|
|
assert!(lst.len() == 2);
|
|
|
|
let rhs = lst.pop().unwrap();
|
|
|
|
let rhs = lst.pop().unwrap();
|
|
|
@ -352,7 +358,7 @@ fn compile_biop(
|
|
|
|
format!(
|
|
|
|
format!(
|
|
|
|
"{} {} {} {}",
|
|
|
|
"{} {} {} {}",
|
|
|
|
op,
|
|
|
|
op,
|
|
|
|
fix_name(&String::from("f32")),
|
|
|
|
fix_name(&String::from(typ)),
|
|
|
|
fix_name(&lhs_id),
|
|
|
|
fix_name(&lhs_id),
|
|
|
|
fix_name(&rhs_id),
|
|
|
|
fix_name(&rhs_id),
|
|
|
|
),
|
|
|
|
),
|
|
|
@ -360,6 +366,68 @@ fn compile_biop(
|
|
|
|
stack.push(id);
|
|
|
|
stack.push(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn compile_comp_constr(
|
|
|
|
|
|
|
|
lst: &mut Vec<Ast>,
|
|
|
|
|
|
|
|
vars: &mut Vec<(String, String)>,
|
|
|
|
|
|
|
|
constants: &mut Vec<(String, String)>,
|
|
|
|
|
|
|
|
types: &mut Vec<String>,
|
|
|
|
|
|
|
|
counter: &mut i32,
|
|
|
|
|
|
|
|
stack: &mut Vec<String>,
|
|
|
|
|
|
|
|
out: &mut Vec<(Option<String>, String)>,
|
|
|
|
|
|
|
|
typ: &str,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
types.push(String::from(typ));
|
|
|
|
|
|
|
|
let typ_parsed = parse_type(&String::from(typ));
|
|
|
|
|
|
|
|
match typ_parsed {
|
|
|
|
|
|
|
|
Type::Vector(_, size) => {
|
|
|
|
|
|
|
|
assert!(lst.len() == size as usize);
|
|
|
|
|
|
|
|
let mut inners: Vec<String> = vec![];
|
|
|
|
|
|
|
|
for _ in 0..size {
|
|
|
|
|
|
|
|
let ast = lst.pop().unwrap();
|
|
|
|
|
|
|
|
compile_ast_ssa(ast, vars, constants, types, counter, stack, out);
|
|
|
|
|
|
|
|
let res_id = stack.pop().unwrap();
|
|
|
|
|
|
|
|
inners.push(res_id);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let id = String::from(counter.to_string());
|
|
|
|
|
|
|
|
*counter += 1;
|
|
|
|
|
|
|
|
let mut out_str = String::new();
|
|
|
|
|
|
|
|
out_str.push_str(
|
|
|
|
|
|
|
|
format!("OpCompositeConstruct {}", fix_name(&String::from(typ))).as_str(),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
inners.reverse();
|
|
|
|
|
|
|
|
for inn in inners {
|
|
|
|
|
|
|
|
out_str.push_str(format!(" {}", fix_name(&inn)).as_str());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
out.push((Some(id.clone()), out_str));
|
|
|
|
|
|
|
|
stack.push(id);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => {
|
|
|
|
|
|
|
|
panic!("Invalid vector!")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn compile_comp_extract( lst: &mut Vec<Ast>,
|
|
|
|
|
|
|
|
vars: &mut Vec<(String, String)>,
|
|
|
|
|
|
|
|
constants: &mut Vec<(String, String)>,
|
|
|
|
|
|
|
|
types: &mut Vec<String>,
|
|
|
|
|
|
|
|
counter: &mut i32,
|
|
|
|
|
|
|
|
stack: &mut Vec<String>,
|
|
|
|
|
|
|
|
out: &mut Vec<(Option<String>, String)>,
|
|
|
|
|
|
|
|
typ: &str, inx: u32) {
|
|
|
|
|
|
|
|
assert!(lst.len() == 1);
|
|
|
|
|
|
|
|
let vec = lst.pop().unwrap();
|
|
|
|
|
|
|
|
compile_ast_ssa(vec, vars, constants, types, counter, stack, out);
|
|
|
|
|
|
|
|
let vec_id = stack.pop().unwrap();
|
|
|
|
|
|
|
|
let id = counter.to_string();
|
|
|
|
|
|
|
|
*counter += 1;
|
|
|
|
|
|
|
|
out.push((
|
|
|
|
|
|
|
|
Some(id.clone()),
|
|
|
|
|
|
|
|
format!("OpCompositeExtract {} {} {}", fix_name(&String::from(typ)), fix_name(&vec_id), inx),
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
stack.push(id);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn compile_ast_ssa(
|
|
|
|
pub fn compile_ast_ssa(
|
|
|
|
ast: Ast,
|
|
|
|
ast: Ast,
|
|
|
|
vars: &mut Vec<(String, String)>,
|
|
|
|
vars: &mut Vec<(String, String)>,
|
|
|
@ -378,13 +446,82 @@ pub fn compile_ast_ssa(
|
|
|
|
let fun_name = fun.symbol();
|
|
|
|
let fun_name = fun.symbol();
|
|
|
|
assert!(fun_name.is_some());
|
|
|
|
assert!(fun_name.is_some());
|
|
|
|
let fun_name = fun_name.unwrap();
|
|
|
|
let fun_name = fun_name.unwrap();
|
|
|
|
|
|
|
|
if fun_name.starts_with(".") {
|
|
|
|
|
|
|
|
let to_split = &fun_name[1..fun_name.len()];
|
|
|
|
|
|
|
|
let split = to_split.split("-").collect::<Vec<&str>>();
|
|
|
|
|
|
|
|
assert!(split.len() == 2);
|
|
|
|
|
|
|
|
let inx = split[0];
|
|
|
|
|
|
|
|
let typ = split[1];
|
|
|
|
|
|
|
|
let inx = str::parse::<u32>(inx).expect("Invalid index!");
|
|
|
|
|
|
|
|
compile_comp_extract(&mut lst, vars, constants, types, counter, stack, out, typ, inx);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if fun_name.starts_with("/") {
|
|
|
|
|
|
|
|
let typ = &fun_name[1..fun_name.len()];
|
|
|
|
|
|
|
|
compile_biop(
|
|
|
|
|
|
|
|
"OpFDiv", &mut lst, vars, constants, types, counter, stack, out, typ,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if fun_name.starts_with("*") {
|
|
|
|
|
|
|
|
let typ = &fun_name[1..fun_name.len()];
|
|
|
|
|
|
|
|
compile_biop(
|
|
|
|
|
|
|
|
"OpFMul", &mut lst, vars, constants, types, counter, stack, out, typ,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if fun_name.starts_with("+") {
|
|
|
|
|
|
|
|
let typ = &fun_name[1..fun_name.len()];
|
|
|
|
|
|
|
|
compile_biop(
|
|
|
|
|
|
|
|
"OpFAdd", &mut lst, vars, constants, types, counter, stack, out, typ,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if fun_name.starts_with("-") {
|
|
|
|
|
|
|
|
let typ = &fun_name[1..fun_name.len()];
|
|
|
|
|
|
|
|
compile_biop(
|
|
|
|
|
|
|
|
"OpFSub", &mut lst, vars, constants, types, counter, stack, out, typ,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if fun_name.starts_with("v") {
|
|
|
|
|
|
|
|
compile_comp_constr(
|
|
|
|
|
|
|
|
&mut lst, vars, constants, types, counter, stack, out, fun_name.as_str(),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if fun_name.starts_with("load-ptr-") {
|
|
|
|
|
|
|
|
let typ = &fun_name[9..fun_name.len()];
|
|
|
|
|
|
|
|
assert!(lst.len() == 1);
|
|
|
|
|
|
|
|
let ptr = lst.pop().unwrap();
|
|
|
|
|
|
|
|
compile_ast_ssa(ptr, vars, constants, types, counter, stack, out);
|
|
|
|
|
|
|
|
let ptr_id = stack.pop().unwrap();
|
|
|
|
|
|
|
|
let id: String = counter.to_string();
|
|
|
|
|
|
|
|
*counter += 1;
|
|
|
|
|
|
|
|
out.push((
|
|
|
|
|
|
|
|
Some(id.clone()),
|
|
|
|
|
|
|
|
format!("OpLoad {} {}", fix_name(&String::from(typ)), fix_name(&ptr_id)),
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
stack.push(id);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
match fun_name.as_str() {
|
|
|
|
match fun_name.as_str() {
|
|
|
|
"store-ptr" => {
|
|
|
|
"store-ptr" => {
|
|
|
|
assert!(lst.len() == 2);
|
|
|
|
assert!(lst.len() == 2);
|
|
|
|
let ptr = lst.pop().unwrap();
|
|
|
|
|
|
|
|
let val = lst.pop().unwrap();
|
|
|
|
let val = lst.pop().unwrap();
|
|
|
|
compile_ast_ssa(ptr, vars, constants, types, counter, stack, out);
|
|
|
|
let ptr = lst.pop().unwrap();
|
|
|
|
compile_ast_ssa(val, vars, constants, types, counter, stack, out);
|
|
|
|
compile_ast_ssa(val, vars, constants, types, counter, stack, out);
|
|
|
|
|
|
|
|
compile_ast_ssa(ptr, vars, constants, types, counter, stack, out);
|
|
|
|
let val_id = stack.pop().unwrap();
|
|
|
|
let val_id = stack.pop().unwrap();
|
|
|
|
let ptr_id = stack.pop().unwrap();
|
|
|
|
let ptr_id = stack.pop().unwrap();
|
|
|
|
out.push((
|
|
|
|
out.push((
|
|
|
@ -392,26 +529,6 @@ pub fn compile_ast_ssa(
|
|
|
|
format!("OpStore {} {}", fix_name(&val_id), fix_name(&ptr_id)),
|
|
|
|
format!("OpStore {} {}", fix_name(&val_id), fix_name(&ptr_id)),
|
|
|
|
));
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"/" => {
|
|
|
|
|
|
|
|
compile_biop(
|
|
|
|
|
|
|
|
"OpFDiv", &mut lst, vars, constants, types, counter, stack, out,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
"*" => {
|
|
|
|
|
|
|
|
compile_biop(
|
|
|
|
|
|
|
|
"OpFMul", &mut lst, vars, constants, types, counter, stack, out,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
"+" => {
|
|
|
|
|
|
|
|
compile_biop(
|
|
|
|
|
|
|
|
"OpFAdd", &mut lst, vars, constants, types, counter, stack, out,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
"-" => {
|
|
|
|
|
|
|
|
compile_biop(
|
|
|
|
|
|
|
|
"OpFSub", &mut lst, vars, constants, types, counter, stack, out,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
s => {
|
|
|
|
s => {
|
|
|
|
panic!(
|
|
|
|
panic!(
|
|
|
|
"Unknown function: {} with params {:#?} in context:\n{:#?}",
|
|
|
|
"Unknown function: {} with params {:#?} in context:\n{:#?}",
|
|
|
@ -534,6 +651,10 @@ pub fn compile_fun_ssa(module: &mut Module, ops: &Vec<(Option<String>, String)>)
|
|
|
|
out_ops.push((None, op.1));
|
|
|
|
out_ops.push((None, op.1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
out_ops.push((None, String::from("OpReturn")));
|
|
|
|
|
|
|
|
out_ops.push((None, String::from("OpFunctionEnd")));
|
|
|
|
|
|
|
|
|
|
|
|
for op in out_ops {
|
|
|
|
for op in out_ops {
|
|
|
|
let split: Vec<String> = op.1.split(" ").map(|s| s.to_string()).collect();
|
|
|
|
let split: Vec<String> = op.1.split(" ").map(|s| s.to_string()).collect();
|
|
|
|
let op_name: String = (&split[0]).clone();
|
|
|
|
let op_name: String = (&split[0]).clone();
|
|
|
|