qemu中反轉比較與交換比較操作數方法

 首先將各種比較操作以枚舉形式定義:
typedef enum {
    TCG_COND_EQ,
    TCG_COND_NE,
    TCG_COND_LT,
    TCG_COND_GE,
    TCG_COND_LE,
    TCG_COND_GT,
    /* unsigned */
    TCG_COND_LTU,
    TCG_COND_GEU,
    TCG_COND_LEU,
    TCG_COND_GTU,
} TCGCond;
注意上述枚舉定義中各種操作的位置順序是非常有講究的,不能任意去調整。


反轉比較的方法:
將比較反轉,如將等於反轉後變爲不等於,小於反轉後變爲不小於(大於等於),結合上面TCGCond的定義,在偶數位置的比較操作與其後繼操作互爲反轉關係。
因此,實現反轉的方法就是將位置信息的最低bit位反轉,如TCG_COND_LE=4,最低bit位反轉爲5,即TCG_COND_GT。反轉函數tcg_invert_cond實現如下:
static inline TCGCond tcg_invert_cond(TCGCond c)
{
    return (TCGCond)(c ^ 1);
}

交換操作數
如a<b,交換後變爲b<a,即a>b
將操作分爲三組:
第一組:
    TCG_COND_EQ,
    TCG_COND_NE,
該組無須交換,因爲a==b與b==a等價,a!=b與b!=a等價

第二組:
    TCG_COND_LT=2
    TCG_COND_GE=3
    TCG_COND_LE=4
    TCG_COND_GT=5
        
第三組:
    /* unsigned */
    TCG_COND_LTU=6
    TCG_COND_GEU=7
    TCG_COND_LEU=8
    TCG_COND_GTU=9

這兩組中第一個與最後一個操作是交換關係,中間兩個操作是交換關係,如a<b與a>b、a>=b與a<=b
    
如何實現交換呢,我們注意到在第二組中存在交換關係的兩個操作序號“或”操作結果爲7,如2|5=7,3|4=7;第三組中存在交換關係的兩個操作序號“或”操作結果爲15,如6|9=15、7|8=15,因此可以使用“異或”操作得到相應的交換操作。

根據以上分析,
第一組操作與自身構成交換關係,與0異或可得到其交換操作;
第二組操作與7異或可得到其交換操作;
第三組操作與15異或可得到其交換操作;

交換函數tcg_swap_cond實現如下:
static inline TCGCond tcg_swap_cond(TCGCond c)
{
    int mask = (c < TCG_COND_LT ? 0 : c < TCG_COND_LTU ? 7 : 15);
    return (TCGCond)(c ^ mask);
}   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章