首先将各种比较操作以枚举形式定义:
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);
}
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);
}