softmmu同构函数的定义

在qemu的softmmu代码中,有很多函数它们的功能是相似的,只是处理的数据类型不同,这里我姑且称之为“同构”函数。如果为它们分别编写函数体,代码量及维护工作量会增加数倍,以softmmu_defs.h文件中声明的函数为例,共声明了16个函数

//softmmu_defs.h
uint8_t REGPARM __ldb_mmu(target_ulong addr, int mmu_idx);
void REGPARM __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx);
uint16_t REGPARM __ldw_mmu(target_ulong addr, int mmu_idx);
void REGPARM __stw_mmu(target_ulong addr, uint16_t val, int mmu_idx);
uint32_t REGPARM __ldl_mmu(target_ulong addr, int mmu_idx);
void REGPARM __stl_mmu(target_ulong addr, uint32_t val, int mmu_idx);
uint64_t REGPARM __ldq_mmu(target_ulong addr, int mmu_idx);
void REGPARM __stq_mmu(target_ulong addr, uint64_t val, int mmu_idx);

uint8_t REGPARM __ldb_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stb_cmmu(target_ulong addr, uint8_t val, int mmu_idx);
uint16_t REGPARM __ldw_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stw_cmmu(target_ulong addr, uint16_t val, int mmu_idx);
uint32_t REGPARM __ldl_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx);
uint64_t REGPARM __ldq_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx);
而定义这些函数仅用了两个函数体。如何实现的呢?就是使用宏glue:
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
分析函数声明我们不难发现,__ld函数首先分为两类,一类是_mmu,另一类是_cmmu,每种类别又分为4个子类,差别体现在函数返回类型上,函数名称同时与之对应。
如返回类型是uint8_t时,函数名称以__ldb开头,表示字节操作。__st函数也具有相同的特点。所以我们不难理解softmmu_template.h文件中的下列定义:

//softmmu_template.h
#define DATA_SIZE (1 << SHIFT)

#if DATA_SIZE == 8
#define SUFFIX q
#define USUFFIX q
#define DATA_TYPE uint64_t
#elif DATA_SIZE == 4
#define SUFFIX l
#define USUFFIX l
#define DATA_TYPE uint32_t
#elif DATA_SIZE == 2
#define SUFFIX w
#define USUFFIX uw
#define DATA_TYPE uint16_t
#elif DATA_SIZE == 1
#define SUFFIX b
#define USUFFIX ub
#define DATA_TYPE uint8_t
#else
#error unsupported data size
#endif

DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                      int mmu_idx)
{
	...
}

#ifndef SOFTMMU_CODE_ACCESS

void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                 DATA_TYPE val,
                                                 int mmu_idx)
{
	...
}

#endif

#undef SHIFT
#undef DATA_TYPE
#undef SUFFIX
#undef USUFFIX

softmmu_template.h仅是头文件,并非函数定义,只有在#include "softmmu_template.h"时才真正定义函数。在exec.c文件中,具有下列语句:

#define MMUSUFFIX _cmmu
#define GETPC() NULL
#define env cpu_single_env
#define SOFTMMU_CODE_ACCESS

#define SHIFT 0
#include "softmmu_template.h"

#define SHIFT 1
#include "softmmu_template.h"

#define SHIFT 2
#include "softmmu_template.h"

#define SHIFT 3
#include "softmmu_template.h"
我们不难发现,这相当于定义了下列函数:

uint8_t REGPARM __ldb_cmmu(target_ulong addr, int mmu_idx)
{
    ...
}
uint16_t REGPARM __ldw_cmmu(target_ulong addr, int mmu_idx)

{
    ...
}
uint32_t REGPARM __ldl_cmmu(target_ulong addr, int mmu_idx)
{
    ...
}
uint64_t REGPARM __ldq_cmmu(target_ulong addr, int mmu_idx)
{
    ...
}
由于exec.c中定义了宏SOFTMMU_CODE_ACCESS,所以这里引用softmmu_template.h文件时并未定义__st函数。实际上在0.14.0版本中没有使用__st*_cmmu函数,所以也没有定义这些函数。

在op_helper.c文件中,存在下面语句:

//op_helper.c
#define MMUSUFFIX _mmu
#define ALIGNED_ONLY

#define SHIFT 0
#include "softmmu_template.h"

#define SHIFT 1
#include "softmmu_template.h"

#define SHIFT 2
#include "softmmu_template.h"

#define SHIFT 3
#include "softmmu_template.h"
而这就相当于定义了下列函数:
uint8_t REGPARM __ldb_mmu(target_ulong addr, int mmu_idx)
{
    ...
}
void REGPARM __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx)
{
    ...
}
uint16_t REGPARM __ldw_mmu(target_ulong addr, int mmu_idx)
{
    ...
}
void REGPARM __stw_mmu(target_ulong addr, uint16_t val, int mmu_idx)
{
    ...
}
uint32_t REGPARM __ldl_mmu(target_ulong addr, int mmu_idx)
{
    ...
}
void REGPARM __stl_mmu(target_ulong addr, uint32_t val, int mmu_idx)
{
    ...
}
uint64_t REGPARM __ldq_mmu(target_ulong addr, int mmu_idx)
{
    ...
}
void REGPARM __stq_mmu(target_ulong addr, uint64_t val, int mmu_idx)
{
    ...
}



你可能感兴趣的:(工作,Access)