Skip to content

feat: support save and restore fp regs for loongarch#14

Merged
yfblock merged 2 commits intoByte-OS:mainfrom
MF-B:main
May 16, 2025
Merged

feat: support save and restore fp regs for loongarch#14
yfblock merged 2 commits intoByte-OS:mainfrom
MF-B:main

Conversation

@MF-B
Copy link
Copy Markdown
Contributor

@MF-B MF-B commented May 15, 2025

Description

Implement floating point support for loongarch

Implementation Details

  • Added a feature flag "fp_simd" in polyhal crate to conditionally enable floating point support
  • Implemented two functions in polyhal::kcontext module:
    • save_fp_regs: Saves floating point register state to a KContext
    • restore_fp_regs: Restores floating point register state from a KContext

How to test

I added a test function in the example crate:

use polyhal::kcontext::KContext;
use polyhal::kcontext::save_fp_regs;
use polyhal::kcontext::restore_fp_regs;

pub fn test_fp_registers() {
    log::info!("Testing FP register save/restore...");
    
    // 创建两个上下文
    let mut context1 = KContext::blank();
    let mut context2 = KContext::blank();
    
    // 定义要使用的浮点常量
    let pi = 3.14159_f64;
    let e = 2.71828_f64;
    let sqrt2 = 1.41421_f64;
    let sqrt3 = 1.73205_f64;
    
    // 初始化一些浮点寄存器值
    unsafe {
        // 使用内联汇编设置一些浮点寄存器的值
        core::arch::asm!(
            "
            fld.d   $f1, {pi_ptr}, 0
            fld.d   $f2, {e_ptr}, 0
            ",
            pi_ptr = in(reg) &pi,
            e_ptr = in(reg) &e,
        );
        
        // 保存当前浮点寄存器状态到context1
        save_fp_regs(&mut context1);
        
        // 改变浮点寄存器的值
        core::arch::asm!(
            "
            fld.d   $f1, {sqrt2_ptr}, 0
            fld.d   $f2, {sqrt3_ptr}, 0
            ",
            sqrt2_ptr = in(reg) &sqrt2,
            sqrt3_ptr = in(reg) &sqrt3,
        );
        
        // 保存更改后的浮点寄存器状态到context2
        save_fp_regs(&mut context2);
        
        // 恢复context1的浮点寄存器状态
        restore_fp_regs(&context1);
        
        // 验证是否成功恢复
        let f1_value: f64 = 0.0;
        let f2_value: f64 = 0.0;
        core::arch::asm!(
            "
            fst.d   $f1, {f1_ptr}, 0
            fst.d   $f2, {f2_ptr}, 0
            ",
            f1_ptr = in(reg) &f1_value,
            f2_ptr = in(reg) &f2_value,
        );
        
        log::info!("After restore, f1 value = {}, f2 value = {}", f1_value, f2_value);
        // 理论上f1_value应该接近3.14159,f2_value应该接近2.71828
        
        if (f1_value - 3.14159).abs() < 0.0001 && (f2_value - 2.71828).abs() < 0.0001 {
            log::info!("FP register save/restore test passed!");
        } else {
            log::error!("FP register save/restore test failed! f1={}, f2={}", f1_value, f2_value);
        }
    }
}

Test Result

With restore_fp_regs disabled:

image

With both two enabled:

image

#[naked]
pub unsafe extern "C" fn restore_fp_regs(to: *const KContext) {
naked_asm!(
"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shrink this code in one line? "xxxx"

Comment thread polyhal/src/components/kcontext/mod.rs Outdated

#[cfg(feature = "fp_simd")]
#[cfg(target_arch = "loongarch64")]
pub_use_arch!(save_fp_regs, restore_fp_regs); No newline at end of file
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a blank new line end of this file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just added a blank line, but it seems it's not displaying on GitHub.

@yfblock yfblock merged commit a4fc344 into Byte-OS:main May 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants