[TriCore] 01.QEMU 虛擬化 TriCore 架構中的寄存器 指令

目錄

1.寄存器宏 - FIELD()

2.寄存器操作 - FIELD_SETTER() & FIELD_GETTER()

3.指令輔助方法 - HELPER()

3.1.輔助宏

3.2.指令示例

3.3.函數調用

4.PSW 寄存器讀寫 - psw_read() & psw_write()


1.寄存器宏 - FIELD()

FIELD() 宏定義寄存器 MASK

// include/hw/registerfields.h
#define FIELD(reg, field, shift, length)                                  \enum { R_ ## reg ## _ ## field ## _SHIFT = (shift)};                  \enum { R_ ## reg ## _ ## field ## _LENGTH = (length)};                \enum { R_ ## reg ## _ ## field ## _MASK =                             \MAKE_64BIT_MASK(shift, length)};

參數含義如下

  • reg:寄存器名稱;

  • field:對應的 FIELD,如 ICR 寄存器的 0~7 位為 CCPN;

  • shift:該 FIELD 在寄存器中的起始比特位,如 PIPN 從 ICR 的第 16 位開始;

  • length:該 FIELD 的長度,如 CCPN 長度的為 8,在 32 位的 ICR 寄存器中占 8 位;

以 TriCore ICR 寄存器為例

// target/tricore/cpu.h
FIELD(ICR, PIPN, 16, 8)

使用 FIELD() 宏定義寄存器,相當于實現如下的操作:

enum {
R_ICR_PIPN_SHIFT = (16)
};enum {
R_ICR_PIPN_LENGTH = (1)
};enum {
R_ICR_PIPN_MASK = MAKE_64BIT_MASK(shift, length)
};
// PIPN 有效位的 Mask 如下
// 0000 0000 1111 1111
// 0000 0000 0000 0000

對照 TC3XX 手冊,這些 FILED() 宏實現寄存器內部相關位域的定義,其中后綴 _13 表示 P1.3(TC27X 平臺)版本,_161 為 P1.6.1 版本(TC37X 平臺)

// target/tricore/cpu.h
FIELD(ICR, IE_161, 15, 1)  // TC3XX,P1.6.1版本
FIELD(ICR, IE_13, 8, 1)    // TC2XX,P1.3版本
FIELD(ICR, PIPN, 16, 8)
FIELD(ICR, CCPN, 0, 8)

2.寄存器操作 - FIELD_SETTER() & FIELD_GETTER()

每個寄存器都定義了對應的 HELPER() 函數,實現對寄存器相關操作,如 get()、set() 等

// target/tricore/cpu.h
FIELD(ICR, IE_161, 15, 1)
FIELD(ICR, IE_13, 8, 1)
FIELD(ICR, PIPN, 16, 8)
FIELD(ICR, CCPN, 0, 8)
uint32_t icr_get_ie(CPUTriCoreState *env);
uint32_t icr_get_ccpn(CPUTriCoreState *env);
void icr_set_ie(CPUTriCoreState *env, uint32_t val);
void icr_set_ccpn(CPUTriCoreState *env, uint32_t val);

使用宏 FIELD_SETTER() 及 FIELD_GETTER() 宏生成具體的函數

// target/tricore/helper.c
FIELD_GETTER_WITH_FEATURE(icr_get_ie, ICR, IE, 161)
FIELD_SETTER_WITH_FEATURE(icr_set_ie, ICR, IE, 161)
FIELD_GETTER(icr_get_ccpn, ICR, CCPN)
FIELD_SETTER(icr_set_ccpn, ICR, CCPN)
---------------------------------------------------------------// target/tricore/helper.c
#define FIELD_GETTER_WITH_FEATURE(NAME, REG, FIELD, FEATURE)     \
uint32_t NAME(CPUTriCoreState *env)                             \
{                                                                \if (tricore_has_feature(env, TRICORE_FEATURE_##FEATURE)) {   \return FIELD_EX32(env->REG, REG, FIELD ## _ ## FEATURE); \}                                                            \return FIELD_EX32(env->REG, REG, FIELD ## _13);              \
}
...#define FIELD_SETTER(NAME, REG, FIELD)                \
void NAME(CPUTriCoreState *env, uint32_t val)        \
{                                                     \env->REG = FIELD_DP32(env->REG, REG, FIELD, val); \
}

3.指令輔助方法 - HELPER()

使用 DEF_HELPER() 宏生成對應的指令,如 svucx 指令、call 指令等

// target/tricore/helper.h
DEF_HELPER_2(call, void, env, i32)
...
DEF_HELPER_1(rslcx, void, env)

HELPER 宏后面的數字表示參數個數,具體的定義如下

// include/exec/helper-head.h
#define DEF_HELPER_0(name, ret) \DEF_HELPER_FLAGS_0(name, 0, ret)
...
#define DEF_HELPER_7(name, ret, t1, t2, t3, t4, t5, t6, t7) \DEF_HELPER_FLAGS_7(name, 0, ret, t1, t2, t3, t4, t5, t6, t7)

DEF_HELPER_FLAGS() 在 helper-info.c.inc、helper-proto.h.inc、henler-gen.h.inc 中均有定義,根據文件包含哪個 .inc 調用對應的宏,例如,在 TriCore 的 translate.c 文件中,將 helper.h 定義為 HELPER_H 宏,從而包含該文件中相關 HELPER 函數的定義,在 helper-info.c.inc 中實現相關宏定義后,將 helper.h 頭文件中定義的 DEF_HELPER_x() 展開

// target/tricore/translate.c
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
...
#define HELPER_H "helper.h"
#include "exec/helper-info.c.inc"
#undef  HELPER_H
-----------------------------------------------------// include/exec/helper-info.c.inc
#define DEF_HELPER_FLAGS_7(NAME, FLAGS, RET, T1, T2, T3, T4, T5, T6, T7)
...
#include HELPER_H
-----------------------------------------------------// target/tricore/helper.h
...
DEF_HELPER_3(add_suov, i32, env, i32, i32)
DEF_HELPER_3(add_h_ssov, i32, env, i32, i32)

3.1.輔助宏

宏展開時使用的相關輔助宏

// include/exec/helper-head.h
#define DEF_HELPER_3(name, ret, t1, t2, t3) \DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3) // 注意參數順序改變
----------------------------------------------------------------------------// include/qemu/compiler.h
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
----------------------------------------------------------------------------// include/exec/helper-head.h
#define HELPER(name) glue(helper_, name) // helper_absdif_b
----------------------------------------------------------------------------// include/exec/helper-info.c.inc
#define str(s) #s // "absdif_b"
----------------------------------------------------------------------------// include/exec/helper-head.h
#define dh_alias_i32 i32
...
#define dh_alias(t) glue(dh_alias_, t) // dh_alias_i32 --> i32
...
#define dh_callflag_i32  0
...
#define dh_callflag(t) glue(dh_callflag_, dh_alias(t)) // dh_callflag_i32 --> 0
...
#define dh_typecode_i32 2
...
#define dh_typecode_ptr 6
...
#define dh_typecode_env dh_typecode_ptr
#define dh_typecode(t) dh_typecode_##t
...
#define dh_typemask(t, n)  (dh_typecode(t) << (n * 3))

3.2.指令示例

以 DEF_HELPER_3(absdif_b, i32, env, i32, i32) 及其對應生成的 gen_helper_absdif_b() 為例,首先是生成對應的 helper_info_xxx() 結構體

// target/tricore/helper.h
DEF_HELPER_3(absdif_b, i32, env, i32, i32)
// 對應:DEF_HELPER_FLAGS_3(absdif_b, 0, i32, env, i32, i32)
----------------------------------------------------------------------------// include/exec/helper-info.c.inc
#define DEF_HELPER_FLAGS_3(NAME, FLAGS, RET, T1, T2, T3)                \TCGHelperInfo glue(helper_info_, NAME) = {                          \.func = HELPER(NAME), .name = str(NAME),                        \.flags = FLAGS | dh_callflag(RET),                              \.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1)            \| dh_typemask(T2, 2) | dh_typemask(T3, 3)             \};
// dh_typemask(RET, 0) --> dh_typemask(i32, 0) --> (dh_typecode(i32) << (0 * 3))
// --> (dh_typecode_i32 << 0) --> 2 << 0 --> 0000 0000 0010// dh_typemask(T1, 1) --> dh_typemask(env, 1) --> (dh_typecode(env) << (1 * 3))
// --> (dh_typecode_ptr << 3) --> 6 << 3 --> 0000 0011 0000// dh_typemask(T2, 2) --> ... --> 2 << 6 --> 0000 1000 0000
// dh_typemask(T3, 3) --> ... --> 2 << 9 --> 0100 0000 0000
----------------------------------------------------------------------------// 展開結果
TCGHelperInfo helper_info_absdif_b = {.func = helper_absdif_b,.name = "absdif_b",.flags = 0,.typemask = 0100 1011 0010
};

繼續解析宏,生成 gen_helper_xxx() 函數

// target/tricore/helper.h
DEF_HELPER_3(absdif_b, i32, env, i32, i32)
// 對應:DEF_HELPER_FLAGS_3(absdif_b, 0, i32, env, i32, i32)
----------------------------------------------------------------------------// include/exec/helper-gen.h.inc
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3)                \
extern TCGHelperInfo glue(helper_info_, name);                          \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret)          \dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3))         \
{                                                                       \tcg_gen_call3(&glue(helper_info_, name), dh_retvar(ret),            \dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3));         \
}
// dh_retvar_decl(ret) --> dh_retvar_decl_i32 --> TCGv_i32 retval,
// dh_arg_decl(t1, 1) --> TCGv_ptr arg1
// dh_arg_decl(t2, 2) --> TCGv_i32 arg2
// dh_arg_decl(t3, 3) --> TCGv_i32 arg3
// &glue(helper_info_, name) --> &helper_info_absdif_b
// dh_retvar(ret) --> --> dh_retvar_i32 --> tcgv_i32_temp(retval)
// dh_arg(t1, 1) --> tcgv_ptr_temp(arg1)
// dh_arg(t2, 2) --> tcgv_i32_temp(arg2)
// dh_arg(t3, 3) --> tcgv_i32_temp(arg3)
----------------------------------------------------------------------------// 展開結果
extern TCGHelperInfo helper_info_absdif_b;
static inline void gen_helper_absdif_b(TCGv_i32 retval, TCGv_ptr arg1, TCGv_i32 arg2, TCGv_i32 arg3)
{tcg_gen_call3(&helper_info_absdif_b, tcgv_i32_temp(retval), tcgv_ptr_temp(arg1), tcgv_i32_temp(arg2), tcgv_i32_temp(arg3));
}

3.3.函數調用

gen_helper_xxx() 具體對應的是 helper_xxx()

// target/tricore/translate.c
/* RR format */
static void decode_rr_accumulator(DisasContext *ctx)
{...switch (op2) {...case OPC2_32_RR_ABSDIF_B:gen_helper_absdif_b(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],cpu_gpr_d[r2]);
----------------------------------------------------------------------------// target/tricore/op_helper.c
uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
{int32_t b, i;int32_t extr_r2;int32_t ovf = 0;int32_t avf = 0;int32_t ret = 0;for (i = 0; i < 4; i++) {extr_r2 = sextract32(r2, i * 8, 8);b = sextract32(r1, i * 8, 8);b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);ovf |= (b > 0x7F) || (b < -0x80);avf |= b ^ b * 2u;ret |= (b & 0xff) << (i * 8);}env->PSW_USB_V = ovf << 31;env->PSW_USB_SV |= env->PSW_USB_V;env->PSW_USB_AV = avf << 24;env->PSW_USB_SAV |= env->PSW_USB_AV;return ret;
}

4.PSW 寄存器讀寫 - psw_read() & psw_write()

用于讀取和修改 TriCore 的 PSW 寄存器

// target/tricore/helper.c
uint32_t psw_read(CPUTriCoreState *env)
{/* clear all USB bits */env->PSW &= 0x7ffffff;/* now set them from the cache */env->PSW |= ((env->PSW_USB_C != 0) << 31);env->PSW |= ((env->PSW_USB_V   & (1 << 31))  >> 1);env->PSW |= ((env->PSW_USB_SV  & (1 << 31))  >> 2);env->PSW |= ((env->PSW_USB_AV  & (1 << 31))  >> 3);env->PSW |= ((env->PSW_USB_SAV & (1 << 31))  >> 4);return env->PSW;
}
----------------------------------------------------------------------------// target/tricore/helper.c
void psw_write(CPUTriCoreState *env, uint32_t val)
{env->PSW_USB_C = (val & MASK_USB_C);env->PSW_USB_V = (val & MASK_USB_V) << 1;env->PSW_USB_SV = (val & MASK_USB_SV) << 2;env->PSW_USB_AV = (val & MASK_USB_AV) << 3;env->PSW_USB_SAV = (val & MASK_USB_SAV) << 4;env->PSW = val;fpu_set_state(env);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82683.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82683.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82683.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《軟件工程》第 4 章 - 需求獲取

在軟件工程中&#xff0c;需求獲取是挖掘用戶真實需求的關鍵步驟&#xff0c;它為后續的設計、開發和測試提供堅實基礎。本章將圍繞需求獲取的流程、方法及工具展開&#xff0c;結合實際案例與 Java 代碼&#xff0c;深入講解這一重要環節。 4.1 軟件需求的初始表示 4.1.1 用例…

react diff 算法

diff 算法作為 Virtual DOM 的加速器&#xff0c;其算法的改進優化是 React 整個界面渲染的基礎和性能的保障&#xff0c;同時也是 React 源碼中最神秘的&#xff0c;最不可思議的部分 diff 算法會幫助我們就算出 VirtualDOM 中真正變化的部分&#xff0c;并只針對該部分進行原…

Gin項目腳手架與標配組件

文章目錄 前言設計思想和原則? 技術棧視頻實況教程sponge 內置了豐富的組件(按需使用)幾個標配常用組件主要技術點另一個參考鏈接 前言 軟件和汽車一樣&#xff0c;由多個重要零部件組裝而成。 本文堆積了一些常用部件&#xff0c;還沒來得及好好整理。先放著。 神兵利器雖多…

【Webtrees 手冊】第 10章 - 用戶體驗

Webtrees 手冊/用戶體驗 < Webtrees 手冊 跳轉到導航跳轉到搜索 信息 手冊部分仍在建設中 請耐心等待或隨意貢獻自己的力量:-)。 第 10 章 - 用戶體驗 <- 章節概述 目錄 1多位系譜學家的合作 1.1家庭研究模型1.2“孤膽戰士”模型1.3示范“本地家庭書”1.4模特“俱樂部”…

Linux 進程概念(下)

目錄 前言 4.進程狀態 一.普遍的操作系統層面上宏觀概念&#xff1a; 二.具體的Linux操作系統的狀態&#xff1a; 5.進程優先級&#xff08;了解&#xff09; 6.其他概念 進程切換 前言 本篇是接著上一篇的內容繼續往下了解進程相關的一些概念&#xff01; 4.進程狀態 運…

使用java實現word轉pdf,html以及rtf轉word,pdf,html

word,rtf的轉換有以下方案&#xff0c;想要免費最靠譜的是LibreOffice方案, LibreOffice 是一款 免費、開源、跨平臺 的辦公軟件套件&#xff0c;旨在為用戶提供高效、全面的辦公工具&#xff0c;適用于個人、企業和教育機構。它支持多種操作系統&#xff08;Windows、macOS、…

IP證書的作用與申請全解析:從安全驗證到部署實踐

在網絡安全領域&#xff0c;IP證書&#xff08;IP SSL證書&#xff09;作為傳統域名SSL證書的補充方案&#xff0c;專為公網IP地址提供HTTPS加密與身份驗證服務。本文將從技術原理、應用場景、申請流程及部署要點四個維度&#xff0c;系統解析IP證書的核心價值與操作指南。 一…

GitLab 18.0 正式發布,15.0 將不再受技術支持,須升級【三】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

超簡單Translation翻譯模型部署

Helsinki-NLP/opus-mt-{en}-{zh}系列翻譯模型可以實現200多種語言翻譯&#xff0c;Helsinki-NLP/opus-mt-en-zh是其中英互譯模型。由于項目需要&#xff0c;在本地進行搭建&#xff0c;并記錄下搭建過程&#xff0c;方便后人。 1. 基本硬件環境 CPU&#xff1a;N年前的 Intel…

Go語言JSON 序列化與反序列化 -《Go語言實戰指南》

JSON&#xff08;JavaScript Object Notation&#xff09;是一種常見的數據交換格式。Go 標準庫提供了 encoding/json 包&#xff0c;用于方便地將結構體與 JSON 之間互轉。 一、序列化&#xff08;Marshal&#xff09; 將 Go 中的數據結構&#xff08;如結構體、map、slice 等…

免費PDF工具-PDF24V9.16.0【win7專用版】

【百度】https://pan.baidu.com/s/1H7kvHudG5JTfxHg-eu2grA?pwd8euh 提取碼: 8euh 【夸克】https://pan.quark.cn/s/92080b2e1f4c 【123】https://www.123912.com/s/0yvtTd-XAHjv https://creator.pdf24.org/listVersions.php

網絡 :序列和反序列化

網絡 &#xff1a;序列和反序列化 &#xff08;一&#xff09;序列和反序列 概念&#xff08;二&#xff09;實例1. 封裝socket 接口2. 制定協議&#xff08;用于實現序列和反序列化&#xff09;3. 計算(實現計算器功能)4. 服務器(將上面所有的類功能調用起來)5. 服務端6.客戶端…

LiveQing 視頻點播流媒體 RTMP 推流服務功能:搭建 RTMP 視頻流媒體服務詳細指南

LiveQing視頻點播流媒體RTMP推流服務功能&#xff1a;搭建RTMP視頻流媒體服務詳細指南 一、流媒體服務搭建二、推流工具準備三、創建鑒權直播間四、獲取推流地址五、配置OBS推流六、推流及播放七、獲取播放地址7.1 頁面查看視頻源地址7.2 接口查詢 八、相關問題解決8.1 大疆無人…

UE5 Niagara 如何讓四元數進行旋轉

Axis Angle中&#xff0c;X,Y,Z分別為旋轉的軸向&#xff0c;W為旋轉的角度&#xff0c;在這里旋轉角度不需要除以2&#xff0c;因為里面已經除了&#xff0c;再將計算好的四元數與要進行旋轉的四元數進行相乘&#xff0c;結果就是按照原來的角度繞著某一軸向旋轉了某一角度

【微服務】SpringBoot 對接飛書審批流程使用詳解

目錄 一、前言 二、前置準備 2.1 開通企業飛書賬戶 2.2 確保賬戶具備多維表操作權限 2.3 獲取飛書開放平臺文檔 2.4 創建應用 2.5 發布應用 2.6 應用添加操作權限 2.7 獲取SDK 三、審批流程對接過程 3.1 配置流程審批定義(流程審批模型) 3.2 自定義應用添加審批AP…

主鍵與唯一鍵詳解:概念、區別與面試要點

主鍵與唯一鍵詳解:概念、區別與面試要點 一、核心概念解析 1.1 主鍵(Primary Key) 主鍵是數據庫表中用于唯一標識每一行記錄的列或列組合,具有以下核心特性: 唯一性:主鍵值在整個表中必須唯一,不允許重復非空性:主鍵列不允許包含NULL值不可變性:主鍵值一旦確立,原則…

前端面試準備-1

1.NodeJS的優缺點 優點&#xff1a;   高并發&#xff08;最重要的優點&#xff09;   適合I/O密集型應用 缺點&#xff1a;   不適合CPU密集型應用&#xff1b;CPU密集型應用給Node帶來的挑戰主要是&#xff1a;由于JavaScript單線程的原因&#xff0c;如果有長時間運行的…

GO并發過高導致程序崩潰如何解決

#作者&#xff1a;曹付江 文章目錄 1.并發過高導致程序崩潰2. 如何解決2.1 利用 channel 的緩存區2.2 利用第三方庫 3 調整系統資源的上限3.1 ulimit3.2 虛擬內存(virtual memory) 1.并發過高導致程序崩潰 看一個非常簡單的例子&#xff1a; func main() {var wg sync.WaitG…

Linux -- gdb/cgdb的認識和使用

預備知識 程序的發布?式有兩種&#xff0c; debug 模式和 release 模式&#xff0c; Linux gcc/g 出來的?進制程 序&#xff0c;默認是 release 模式。 要使?gdb調試&#xff0c;必須在源代碼?成?進制程序的時候, 加上 -g 選項&#xff0c;如果沒有添加&#x…

window 顯示驅動開發-Direct3D 呈現性能改進(四)

調用資源創建、映射和取消映射函數的行為更改 對于 WDDM 1.3 及更高版本驅動程序實現的這些函數&#xff0c;Direct3D 運行時為映射默認方案提供一組受限的輸入值。 這些受限值僅適用于支持功能級別 11.1 及更高版本的驅動程序。 CreateResource (D3D11) 函數— 這些輸入 D3…