add the openrisc int instruction helpers. Signed-off-by: Jia Liu <pro...@gmail.com> --- Makefile.target | 2 +- target-openrisc/helper.h | 7 +++ target-openrisc/int_helper.c | 126 ++++++++++++++++++++++++++++++++++++++++++ target-openrisc/translate.c | 14 ++--- 4 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 target-openrisc/int_helper.c
diff --git a/Makefile.target b/Makefile.target index ed5f0b0..9bebdb3 100644 --- a/Makefile.target +++ b/Makefile.target @@ -101,7 +101,7 @@ endif libobj-$(TARGET_SPARC) += int32_helper.o libobj-$(TARGET_SPARC64) += int64_helper.o libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o -libobj-$(TARGET_OPENRISC) += excp.o excp_helper.o intrp_helper.o mem.o mem_helper.o +libobj-$(TARGET_OPENRISC) += excp.o excp_helper.o int_helper.o intrp_helper.o mem.o mem_helper.o libobj-y += disas.o libobj-$(CONFIG_TCI_DIS) += tci-dis.o diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h index a0fb8c4..f5ed117 100644 --- a/target-openrisc/helper.h +++ b/target-openrisc/helper.h @@ -23,6 +23,13 @@ /* exception */ DEF_HELPER_FLAGS_2(exception, 0, void, env, i32) +/* int */ +DEF_HELPER_FLAGS_1(ff1, 0, tl, tl) +DEF_HELPER_FLAGS_1(fl1, 0, tl, tl) +DEF_HELPER_FLAGS_3(add, 0, tl, env, tl, tl) +DEF_HELPER_FLAGS_3(addc, 0, tl, env, tl, tl) +DEF_HELPER_FLAGS_3(sub, 0, tl, env, tl, tl) + /* interrupt */ DEF_HELPER_FLAGS_1(rfe, 0, void, env) diff --git a/target-openrisc/int_helper.c b/target-openrisc/int_helper.c new file mode 100644 index 0000000..540b941 --- /dev/null +++ b/target-openrisc/int_helper.c @@ -0,0 +1,126 @@ +/* + * OpenRISC int helper routines + * + * Copyright (c) 2011-2012 Jia Liu <pro...@gmail.com> + * Feng Gao <gf91...@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + */ + +#include "cpu.h" +#include "helper.h" +#include "excp.h" + +target_ulong HELPER(ff1)(target_ulong x) +{ + target_ulong n = 0; + + if (x == 0) { + return 0; + } + + for (n = 32; x; n--) { + x <<= 1; + } + return n+1; +} + +target_ulong HELPER(fl1)(target_ulong x) +{ + target_ulong n = 0; + + if (x == 0) { + return 0; + } + + for (n = 0; x; n++) { + x >>= 1; + } + return n; +} + +/* l.add, l.addc, l.addi, l.addic, l.sub. for overflow exception. */ +target_ulong HELPER(add)(CPUOPENRISCState * env, target_ulong a, target_ulong b) +{ + target_ulong result; + result = a + b; + + if (result < a) { + env->sr |= SR_CY; + } else { + env->sr &= ~SR_CY; + } + + if ((a ^ b ^ -1) & (a ^ result)) { + env->sr |= SR_OV; + if (env->sr & SR_OVE) { + raise_exception(env, EXCP_RANGE); + } + } else { + env->sr &= ~SR_OV; + } + return result; +} + +target_ulong HELPER(addc)(CPUOPENRISCState * env, + target_ulong a, target_ulong b) +{ + target_ulong result; + int cf = env->sr & SR_CY; + + if (!cf) { + result = a + b; + cf = result < a; + } else { + result = a + b + 1; + cf = result <= a; + } + + if (cf) { + env->sr |= SR_CY; + } else { + env->sr &= ~SR_CY; + } + + if ((a ^ b ^ -1) & (a ^ result)) { + env->sr |= SR_OV; + if (env->sr & SR_OVE) { + raise_exception(env, EXCP_RANGE); + } + } else { + env->sr &= ~SR_OV; + } + return result; +} + +target_ulong HELPER(sub)(CPUOPENRISCState * env, target_ulong a, target_ulong b) +{ + target_ulong result; + result = a - b; + if (a >= b) { + env->sr |= SR_CY; + } else { + env->sr &= ~SR_CY; + } + + if ((a ^ b) & (a ^ result)) { + env->sr |= SR_OV; + if (env->sr & SR_OVE) { + raise_exception(env, EXCP_RANGE); + } + } else { + env->sr &= ~SR_OV; + } + return result; +} diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index a1264c9..dffc8a7 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -203,7 +203,7 @@ static void dec_calc(DisasContext *dc, CPUOPENRISCState *env, uint32_t insn) switch (op1) { case 0x00: /*l.add*/ LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb); - /* Aha, we do need a helper here for add */ + gen_helper_add(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); break; default: break; @@ -214,7 +214,7 @@ static void dec_calc(DisasContext *dc, CPUOPENRISCState *env, uint32_t insn) switch (op1) { case 0x00: LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb); - /* Aha, we do need a helper here for addc */ + gen_helper_addc(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); break; default: break; @@ -225,7 +225,7 @@ static void dec_calc(DisasContext *dc, CPUOPENRISCState *env, uint32_t insn) switch (op1) { case 0x00: LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb); - /* Aha, we do need a helper here for sub */ + gen_helper_sub(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); break; default: break; @@ -352,11 +352,11 @@ static void dec_calc(DisasContext *dc, CPUOPENRISCState *env, uint32_t insn) switch (op1) { case 0x00: /*l.ff1*/ LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb); - /* ff1 need a helper here */ + gen_helper_ff1(cpu_R[rd], cpu_R[ra]); break; case 0x01: /*l.fl1*/ LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb); - /* fl1 need a helper here */ + gen_helper_fl1(cpu_R[rd], cpu_R[ra]); break; default: break; @@ -659,7 +659,7 @@ static void dec_misc(DisasContext *dc, CPUOPENRISCState *env, uint32_t insn) LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16); { TCGv t0 = tcg_const_tl(sign_extend(I16, 16)); - /* Aha, we do need a helper here for addi */ + gen_helper_add(cpu_R[rd], cpu_env, cpu_R[ra], t0); tcg_temp_free(t0); } break; @@ -668,7 +668,7 @@ static void dec_misc(DisasContext *dc, CPUOPENRISCState *env, uint32_t insn) LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16); { TCGv t0 = tcg_const_tl(sign_extend(I16, 16)); - /* Aha, we do need a helper here for addic */ + gen_helper_addc(cpu_R[rd], cpu_env, cpu_R[ra], t0); tcg_temp_free(t0); } break; -- 1.7.9.5