Message ID | 20190810041255.6820-17-jan.bobek@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | rewrite MMX/SSE instruction translation | expand |
On 8/10/19 5:12 AM, Jan Bobek wrote: > +#define INSNOP_INIT(opT, init_stmt) \ > + static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \ > + int modrm, insnop_t(opT) *op) \ > + { \ > + init_stmt; \ > + } ... > +#define INSNOP_INIT_FAIL return 1 > +#define INSNOP_INIT_OK(x) return ((*(op) = (x)), 0) Return bool and true on success. r~
On 8/13/19 2:07 AM, Richard Henderson wrote: > On 8/10/19 5:12 AM, Jan Bobek wrote: >> +#define INSNOP_INIT(opT, init_stmt) \ >> + static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \ >> + int modrm, insnop_t(opT) *op) \ >> + { \ >> + init_stmt; \ >> + } > ... >> +#define INSNOP_INIT_FAIL return 1 >> +#define INSNOP_INIT_OK(x) return ((*(op) = (x)), 0) > > Return bool and true on success. So, the reason why I did this "inverted" logic (0 = success, 1 = failure) is because I was anticipating I might need to differentiate between two or more different failures, in which case returning different non-zero values for different error cases makes perfect sense. I have not made use of it yet, but I'd rather hold on to this idiom at least for now, until I am 100 % sure it really is unnecessary. -Jan
On 8/15/19 1:00 AM, Jan Bobek wrote: > On 8/13/19 2:07 AM, Richard Henderson wrote: >> On 8/10/19 5:12 AM, Jan Bobek wrote: >>> +#define INSNOP_INIT(opT, init_stmt) \ >>> + static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \ >>> + int modrm, insnop_t(opT) *op) \ >>> + { \ >>> + init_stmt; \ >>> + } >> ... >>> +#define INSNOP_INIT_FAIL return 1 >>> +#define INSNOP_INIT_OK(x) return ((*(op) = (x)), 0) >> >> Return bool and true on success. > > So, the reason why I did this "inverted" logic (0 = success, 1 = > failure) is because I was anticipating I might need to differentiate > between two or more different failures, in which case returning > different non-zero values for different error cases makes perfect > sense. I have not made use of it yet, but I'd rather hold on to this > idiom at least for now, until I am 100 % sure it really is > unnecessary. In that case "int" still isn't the best return type -- an enumeration would be. r~
diff --git a/target/i386/translate.c b/target/i386/translate.c index 508d584584..109e4922eb 100644 --- a/target/i386/translate.c +++ b/target/i386/translate.c @@ -4545,6 +4545,47 @@ static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat) } } +/* + * Core instruction operand infrastructure + */ +#define insnop_t(opT) insnop_ ## opT ## _t +#define insnop_init(opT) insnop_ ## opT ## _init +#define insnop_prepare(opT) insnop_ ## opT ## _prepare +#define insnop_finalize(opT) insnop_ ## opT ## _finalize + +#define TYPEDEF_INSNOP_T(opT, type) \ + typedef type insnop_t(opT); +#define INSNOP_INIT(opT, init_stmt) \ + static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \ + int modrm, insnop_t(opT) *op) \ + { \ + init_stmt; \ + } +#define INSNOP_PREPARE(opT, prepare_stmt) \ + static void insnop_prepare(opT)(CPUX86State *env, DisasContext *s, \ + int modrm, insnop_t(opT) *op) \ + { \ + prepare_stmt; \ + } +#define INSNOP_FINALIZE(opT, finalize_stmt) \ + static void insnop_finalize(opT)(CPUX86State *env, DisasContext *s, \ + int modrm, insnop_t(opT) *op) \ + { \ + finalize_stmt; \ + } +#define INSNOP(opT, type, init_stmt, prepare_stmt, finalize_stmt) \ + TYPEDEF_INSNOP_T(opT, type) \ + INSNOP_INIT(opT, init_stmt) \ + INSNOP_PREPARE(opT, prepare_stmt) \ + INSNOP_FINALIZE(opT, finalize_stmt) + +#define INSNOP_INIT_FAIL return 1 +#define INSNOP_INIT_OK(x) return ((*(op) = (x)), 0) +#define INSNOP_PREPARE_NOOP /* no-op */ +#define INSNOP_PREPARE_INVALID g_assert_not_reached() +#define INSNOP_FINALIZE_NOOP /* no-op */ +#define INSNOP_FINALIZE_INVALID g_assert_not_reached() + static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b) { enum {
insnop_t and the init, prepare and finalize functions form the basis of instruction operand decoding. Introduce macros for defining a generic instruction operand; use cases for operand decoding will be introduced later with instruction translators. Signed-off-by: Jan Bobek <jan.bobek@gmail.com> --- target/i386/translate.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)