浏览代码

Merge pull request #135 from woshiluo/patch/float-unaligned

feat(prototyper): support unaligned float load/store
Luo Jia / Zhouqi Jiang 1 天之前
父节点
当前提交
ca3c99d608
共有 3 个文件被更改,包括 69 次插入10 次删除
  1. 14 9
      prototyper/prototyper/src/sbi/trap/handler.rs
  2. 54 0
      prototyper/prototyper/src/sbi/trap/helper.rs
  3. 1 1
      xtask/src/prototyper.rs

+ 14 - 9
prototyper/prototyper/src/sbi/trap/handler.rs

@@ -234,16 +234,19 @@ pub extern "C" fn load_misaligned_handler(ctx: EntireContext) -> EntireResult {
             _ => panic!("Invalid len"),
         },
         VarType::Float => match len {
-            // 4 => raw_data as f32 as usize,
-            // 8 => raw_data as f64 as usize,
-            _ => panic!("Misaligned float is unsupported"),
+            4 => raw_data as u32 as usize,
+            8 => raw_data as u64 as usize,
+            _ => panic!("Invalid len"),
         },
     };
     debug!(
         "read 0x{:x} from 0x{:x} to x{}, len 0x{:x}",
         read_data, current_addr, target_reg, len
     );
-    save_reg_x(&mut ctx, target_reg as usize, read_data);
+    match var_type {
+        VarType::Signed | VarType::UnSigned => save_reg_x(&mut ctx, target_reg as usize, read_data),
+        VarType::Float => set_reg_f(target_reg as usize, len, read_data),
+    };
     mepc::write(current_pc + inst_len);
     ctx.restore()
 }
@@ -273,9 +276,11 @@ pub extern "C" fn store_misaligned_handler(ctx: EntireContext) -> EntireResult {
         _ => panic!("Unsupported inst"),
     };
     let (target_reg, var_type, len) = inst_type;
-    let raw_data = get_reg_x(&mut ctx, target_reg as usize);
+    let raw_data = match var_type {
+        VarType::Signed | VarType::UnSigned => get_reg_x(&mut ctx, target_reg as usize),
+        VarType::Float => get_reg_f(target_reg as usize, len),
+    };
 
-    // TODO: Float support
     let read_data = match var_type {
         VarType::Signed => match len {
             _ => panic!("Can not store signed data"),
@@ -288,9 +293,9 @@ pub extern "C" fn store_misaligned_handler(ctx: EntireContext) -> EntireResult {
             _ => panic!("Invalid len"),
         },
         VarType::Float => match len {
-            // 4 => (raw_data as f32).to_le_bytes().to_vec(),
-            // 8 => (raw_data as f64).to_le_bytes().to_vec(),
-            _ => panic!("Misaligned float is unsupported"),
+            4 => &(raw_data as u32).to_le_bytes()[..],
+            8 => &(raw_data as u64).to_le_bytes()[..],
+            _ => panic!("Invalid len"),
         },
     };
 

+ 54 - 0
prototyper/prototyper/src/sbi/trap/helper.rs

@@ -159,3 +159,57 @@ pub fn get_reg_x(ctx: &mut EntireContextSeparated, reg_id: usize) -> usize {
         _ => panic!(),
     }
 }
+
+pub fn get_reg_f(reg_id: usize, len: usize) -> usize {
+    let mut data: usize;
+    match len {
+        4 => {
+            seq_macro::seq!(N in 0..32 {
+                match reg_id {
+                    #(
+                        N => unsafe { asm!("fmv.x.w {data}, f{x}", data = out(reg) data, x = const N, options(nomem)) },
+                    )*
+                    _ => unreachable!()
+                }
+            });
+        }
+        8 => {
+            seq_macro::seq!(N in 0..32 {
+                match reg_id {
+                    #(
+                        N => unsafe { asm!("fmv.x.d {data}, f{x}", data = out(reg) data, x = const N, options(nomem)) },
+                    )*
+                    _ => unreachable!()
+                }
+            });
+        }
+        _ => todo!(),
+    }
+    data
+}
+
+pub fn set_reg_f(reg_id: usize, len: usize, value: usize) {
+    match len {
+        4 => {
+            seq_macro::seq!(N in 0..32 {
+                match reg_id {
+                    #(
+                        N => unsafe { asm!("fmv.w.x f{x}, {data}", data = in(reg) value, x = const N, options(nomem)) },
+                    )*
+                    _ => unreachable!()
+                }
+            });
+        }
+        8 => {
+            seq_macro::seq!(N in 0..32 {
+                match reg_id {
+                    #(
+                        N => unsafe { asm!("fmv.d.x f{x}, {data}", data = in(reg) value, x = const N, options(nomem)) },
+                    )*
+                    _ => unreachable!()
+                }
+            });
+        }
+        _ => todo!(),
+    }
+}

+ 1 - 1
xtask/src/prototyper.rs

@@ -25,7 +25,7 @@ pub struct PrototyperArg {
     pub config_file: Option<PathBuf>,
 }
 
-const ARCH: &str = "riscv64imac-unknown-none-elf";
+const ARCH: &str = "riscv64gc-unknown-none-elf";
 const PACKAGE_NAME: &str = "rustsbi-prototyper";
 
 #[must_use]