Provides some code-generation macros intended to be used by the user when generating code on instrumentation points.
Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu> --- cpu-all.h | 2 + instrument/generate.h | 124 +++++++++++++++++++++++++++++++++++++++++++++++++ instrument/types.h | 33 +++++++++++++ 3 files changed, 159 insertions(+), 0 deletions(-) create mode 100644 instrument/generate.h create mode 100644 instrument/types.h diff --git a/cpu-all.h b/cpu-all.h index 1be1c60..b15253f 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -24,6 +24,8 @@ #if defined(CONFIG_INSTRUMENT) +#include "instrument/types.h" +#include "instrument/generate.h" #include "instrument/control.h" #include "instrument/state.h" diff --git a/instrument/generate.h b/instrument/generate.h new file mode 100644 index 0000000..7e4b35c --- /dev/null +++ b/instrument/generate.h @@ -0,0 +1,124 @@ +/* + * User macros for code generation in static instrumentation points. + * + * Copyright (c) 2010 Lluís Vilanova <vilan...@ac.upc.edu> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef INSTRUMENT__GENERATE_H +#define INSTRUMENT__GENERATE_H + +/* Generate calls to code helpers (callback) with the provided arguments. + * + * Note that each argument comes in pairs: the type (instr_arg_type_t) and the + * value. + */ + +#define INSTR_GEN_0(callback) \ + do { \ + gen_helper_ ##callback(); \ + } while(0) + +#define INSTR_GEN_1(callback, type1, arg1) \ + do { \ + __INSTR_ARG_DECL(tmp1, type1, arg1); \ + gen_helper_ ##callback (tmp1); \ + __INSTR_ARG_FREE(tmp1, type1); \ + } while(0) + +#define INSTR_GEN_2(callback, type1, arg1, type2, arg2) \ + do { \ + __INSTR_ARG_DECL(tmp1, type1, arg1); \ + __INSTR_ARG_DECL(tmp2, type2, arg2); \ + gen_helper_ ##callback (tmp1, tmp2); \ + __INSTR_ARG_FREE(tmp1, type1); \ + __INSTR_ARG_FREE(tmp2, type2); \ + } while(0) + +#define INSTR_GEN_3(callback, type1, arg1, type2, arg2, type3, arg3) \ + do { \ + __INSTR_ARG_DECL(tmp1, type1, arg1); \ + __INSTR_ARG_DECL(tmp2, type2, arg2); \ + __INSTR_ARG_DECL(tmp3, type3, arg3); \ + gen_helper_ ##callback (tmp1, tmp2, tmp3); \ + __INSTR_ARG_FREE(tmp1, type1); \ + __INSTR_ARG_FREE(tmp2, type2); \ + __INSTR_ARG_FREE(tmp3, type3); \ + } while(0) + +#define INSTR_GEN_4(callback, type1, arg1, type2, arg2, type3, arg3, \ + type4, arg4) \ + do { \ + __INSTR_ARG_DECL(tmp1, type1, arg1); \ + __INSTR_ARG_DECL(tmp2, type2, arg2); \ + __INSTR_ARG_DECL(tmp3, type3, arg3); \ + __INSTR_ARG_DECL(tmp4, type4, arg4); \ + gen_helper_ ##callback (tmp1, tmp2, tmp3, tmp4); \ + __INSTR_ARG_FREE(tmp1, type1); \ + __INSTR_ARG_FREE(tmp2, type2); \ + __INSTR_ARG_FREE(tmp3, type3); \ + __INSTR_ARG_FREE(tmp4, type4); \ + } while(0) + +#define INSTR_GEN_5(callback, type1, arg1, type2, arg2, type3, arg3, \ + type4, arg4, type5, arg5) \ + do { \ + __INSTR_ARG_DECL(tmp1, type1, arg1); \ + __INSTR_ARG_DECL(tmp2, type2, arg2); \ + __INSTR_ARG_DECL(tmp3, type3, arg3); \ + __INSTR_ARG_DECL(tmp4, type4, arg4); \ + __INSTR_ARG_DECL(tmp5, type5, arg5); \ + gen_helper_ ##callback (tmp1, tmp2, tmp3, tmp4, tmp5); \ + __INSTR_ARG_FREE(tmp1, type1); \ + __INSTR_ARG_FREE(tmp2, type2); \ + __INSTR_ARG_FREE(tmp3, type3); \ + __INSTR_ARG_FREE(tmp4, type4); \ + __INSTR_ARG_FREE(tmp5, type5); \ + } while(0) + + +/* Internal API */ + +/* Argument type conversion into TCGv temporaries */ + +#define __INSTR_ARG_I32_DECL(tcg, value) TCGv_i32 tcg = tcg_const_i32((value)) +#define __INSTR_ARG_I64_DECL(tcg, value) TCGv_i64 tcg = tcg_const_i64((value)) +#if TARGET_LONG_BITS == 64 +#define __INSTR_ARG_TUL_DECL(tcg, value) __INSTR_ARG_I64_DECL(tcg, value) +#define __INSTR_ARG_TCGv_i64_DECL(tcg, value) TCGv_i64 tcg = value +#else +#define __INSTR_ARG_TUL_DECL(tcg, value) __INSTR_ARG_I32_DECL(tcg, value) +#define __INSTR_ARG_TCGv_i32_DECL(tcg, value) TCGv_i32 tcg = value +#endif + +#define __INSTR_ARG_DECL(tcg, type, value) __INSTR_ARG_ ##type ##_DECL(tcg, value) + + +/* Free TCGv temporaries */ + +#define __INSTR_ARG_I32_FREE(tcg) tcg_temp_free_i32(tcg) +#define __INSTR_ARG_I64_FREE(tcg) tcg_temp_free_i64(tcg) +#if TARGET_LONG_BITS == 64 +#define __INSTR_ARG_TUL_FREE(tcg) __INSTR_ARG_I64_FREE(tcg) +#else +#define __INSTR_ARG_TUL_FREE(tcg) __INSTR_ARG_I32_FREE(tcg) +#endif +#define __INSTR_ARG_TCGv_i64_FREE(tcg) +#define __INSTR_ARG_TCGv_i32_FREE(tcg) +#define __INSTR_ARG_TCGv_FREE(tcg) + +#define __INSTR_ARG_FREE(tcg, type) __INSTR_ARG_ ##type ##_FREE(tcg) + +#endif /* INSTRUMENT__GENERATE_H */ diff --git a/instrument/types.h b/instrument/types.h new file mode 100644 index 0000000..eb4036b --- /dev/null +++ b/instrument/types.h @@ -0,0 +1,33 @@ +/* + * Static instrumentation data types. + * + * Copyright (c) 2010 Lluís Vilanova <vilan...@ac.upc.edu> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef INSTRUMENT__TYPES_H +#define INSTRUMENT__TYPES_H + +/** Instrumentation argument types. */ +typedef enum { + INSTR_ARG_I32, /**< immediate of 32bits */ + INSTR_ARG_I64, /**< immediate of 64bits */ + INSTR_ARG_TUL, /**< immediate target_ulong */ + INSTR_ARG_TCGv_i32, /**< 32-bit TCGv variable */ + INSTR_ARG_TCGv_i64, /**< 64-bit TCGv variable */ + INSTR_ARG_TCGv, /**< target-bit TCGv variable*/ +} instr_arg_type_t; + +#endif /* INSTRUMENT__TYPES_H */ -- 1.7.1 -- "And it's much the same thing with knowledge, for whenever you learn something new, the whole world becomes that much richer." -- The Princess of Pure Reason, as told by Norton Juster in The Phantom Tollbooth