diff --git a/target-tilegx/Makefile.objs b/target-tilegx/Makefile.objs index 8b3dc76d84..0db778f407 100644 --- a/target-tilegx/Makefile.objs +++ b/target-tilegx/Makefile.objs @@ -1 +1 @@ -obj-y += cpu.o translate.o helper.o +obj-y += cpu.o translate.o helper.o simd_helper.o diff --git a/target-tilegx/helper.h b/target-tilegx/helper.h index 644d313e79..766f5f2f9c 100644 --- a/target-tilegx/helper.h +++ b/target-tilegx/helper.h @@ -4,3 +4,7 @@ DEF_HELPER_FLAGS_1(cnttz, TCG_CALL_NO_RWG_SE, i64, i64) DEF_HELPER_FLAGS_1(pcnt, TCG_CALL_NO_RWG_SE, i64, i64) DEF_HELPER_FLAGS_1(revbits, TCG_CALL_NO_RWG_SE, i64, i64) DEF_HELPER_FLAGS_3(shufflebytes, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64) + +DEF_HELPER_FLAGS_2(v1shl, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(v1shru, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(v1shrs, TCG_CALL_NO_RWG_SE, i64, i64, i64) diff --git a/target-tilegx/simd_helper.c b/target-tilegx/simd_helper.c new file mode 100644 index 0000000000..b9319292f3 --- /dev/null +++ b/target-tilegx/simd_helper.c @@ -0,0 +1,55 @@ +/* + * QEMU TILE-Gx helpers + * + * Copyright (c) 2015 Chen Gang + * + * 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.1 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 + * + */ + +#include "cpu.h" +#include "qemu-common.h" +#include "exec/helper-proto.h" + + +uint64_t helper_v1shl(uint64_t a, uint64_t b) +{ + uint64_t m; + + b &= 7; + m = 0x0101010101010101ULL * (0xff >> b); + return (a & m) << b; +} + +uint64_t helper_v1shru(uint64_t a, uint64_t b) +{ + uint64_t m; + + b &= 7; + m = 0x0101010101010101ULL * ((0xff << b) & 0xff); + return (a & m) >> b; +} + +uint64_t helper_v1shrs(uint64_t a, uint64_t b) +{ + uint64_t r = 0; + int i; + + b &= 7; + for (i = 0; i < 64; i += 8) { + int64_t ae = (int8_t)(a >> i); + r |= ((ae >> b) & 0xff) << i; + } + return r; +} diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c index 65b610e542..e70c3e5ab7 100644 --- a/target-tilegx/translate.c +++ b/target-tilegx/translate.c @@ -1077,12 +1077,22 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext, case OE_RRR(V1MZ, 0, X1): case OE_RRR(V1SADAU, 0, X0): case OE_RRR(V1SADU, 0, X0): + return TILEGX_EXCP_OPCODE_UNIMPLEMENTED; case OE_RRR(V1SHL, 0, X0): case OE_RRR(V1SHL, 0, X1): + gen_helper_v1shl(tdest, tsrca, tsrcb); + mnemonic = "v1shl"; + break; case OE_RRR(V1SHRS, 0, X0): case OE_RRR(V1SHRS, 0, X1): + gen_helper_v1shrs(tdest, tsrca, tsrcb); + mnemonic = "v1shrs"; + break; case OE_RRR(V1SHRU, 0, X0): case OE_RRR(V1SHRU, 0, X1): + gen_helper_v1shru(tdest, tsrca, tsrcb); + mnemonic = "v1shru"; + break; case OE_RRR(V1SUBUC, 0, X0): case OE_RRR(V1SUBUC, 0, X1): case OE_RRR(V1SUB, 0, X0): @@ -1199,6 +1209,7 @@ static TileExcp gen_rri_opcode(DisasContext *dc, unsigned opext, const char *mnemonic; TCGMemOp memop; int i2, i3; + TCGv t0; switch (opext) { case OE(ADDI_OPCODE_Y0, 0, Y0): @@ -1401,7 +1412,11 @@ static TileExcp gen_rri_opcode(DisasContext *dc, unsigned opext, break; case OE_SH(V1SHRSI, X0): case OE_SH(V1SHRSI, X1): - return TILEGX_EXCP_OPCODE_UNIMPLEMENTED; + t0 = tcg_const_tl(imm & 7); + gen_helper_v1shrs(tdest, tsrca, t0); + tcg_temp_free(t0); + mnemonic = "v1shrsi"; + break; case OE_SH(V1SHRUI, X0): case OE_SH(V1SHRUI, X1): i2 = imm & 7;