| /*---------------------------------------------------------------*/ |
| /*--- begin guest_tilegx_helpers.c ---*/ |
| /*---------------------------------------------------------------*/ |
| |
| /* |
| This file is part of Valgrind, a dynamic binary instrumentation |
| framework. |
| |
| Copyright (C) 2010-2015 Tilera Corp. |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License as |
| published by the Free Software Foundation; either version 2 of the |
| License, or (at your option) any later version. |
| |
| This program 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 |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 02111-1307, USA. |
| |
| The GNU General Public License is contained in the file COPYING. |
| */ |
| |
| /* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */ |
| |
| #include "libvex_basictypes.h" |
| #include "libvex_emnote.h" |
| #include "libvex_guest_tilegx.h" |
| #include "libvex_ir.h" |
| #include "libvex.h" |
| |
| #include "main_util.h" |
| #include "guest_generic_bb_to_IR.h" |
| #include "guest_tilegx_defs.h" |
| |
| /* This file contains helper functions for tilegx guest code. Calls to |
| these functions are generated by the back end. |
| */ |
| |
| #define ALWAYSDEFD(field) \ |
| { offsetof(VexGuestTILEGXState, field), \ |
| (sizeof ((VexGuestTILEGXState*)0)->field) } |
| |
| IRExpr *guest_tilegx_spechelper ( const HChar * function_name, IRExpr ** args, |
| IRStmt ** precedingStmts, Int n_precedingStmts) |
| { |
| return NULL; |
| } |
| |
| /* VISIBLE TO LIBVEX CLIENT */ |
| void LibVEX_GuestTILEGX_initialise ( VexGuestTILEGXState * vex_state ) |
| { |
| vex_state->guest_r0 = 0; |
| vex_state->guest_r1 = 0; |
| vex_state->guest_r2 = 0; |
| vex_state->guest_r3 = 0; |
| vex_state->guest_r4 = 0; |
| vex_state->guest_r5 = 0; |
| vex_state->guest_r6 = 0; |
| vex_state->guest_r7 = 0; |
| vex_state->guest_r8 = 0; |
| vex_state->guest_r9 = 0; |
| vex_state->guest_r10 = 0; |
| vex_state->guest_r11 = 0; |
| vex_state->guest_r12 = 0; |
| vex_state->guest_r13 = 0; |
| vex_state->guest_r14 = 0; |
| vex_state->guest_r15 = 0; |
| vex_state->guest_r16 = 0; |
| vex_state->guest_r17 = 0; |
| vex_state->guest_r18 = 0; |
| vex_state->guest_r19 = 0; |
| vex_state->guest_r20 = 0; |
| vex_state->guest_r21 = 0; |
| vex_state->guest_r22 = 0; |
| vex_state->guest_r23 = 0; |
| vex_state->guest_r24 = 0; |
| vex_state->guest_r25 = 0; |
| vex_state->guest_r26 = 0; |
| vex_state->guest_r27 = 0; |
| vex_state->guest_r28 = 0; |
| vex_state->guest_r29 = 0; |
| vex_state->guest_r30 = 0; |
| vex_state->guest_r31 = 0; |
| vex_state->guest_r32 = 0; |
| vex_state->guest_r33 = 0; |
| vex_state->guest_r34 = 0; |
| vex_state->guest_r35 = 0; |
| vex_state->guest_r36 = 0; |
| vex_state->guest_r37 = 0; |
| vex_state->guest_r38 = 0; |
| vex_state->guest_r39 = 0; |
| vex_state->guest_r40 = 0; |
| vex_state->guest_r41 = 0; |
| vex_state->guest_r42 = 0; |
| vex_state->guest_r43 = 0; |
| vex_state->guest_r44 = 0; |
| vex_state->guest_r45 = 0; |
| vex_state->guest_r46 = 0; |
| vex_state->guest_r47 = 0; |
| vex_state->guest_r48 = 0; |
| vex_state->guest_r49 = 0; |
| vex_state->guest_r50 = 0; |
| vex_state->guest_r51 = 0; |
| vex_state->guest_r52 = 0; |
| vex_state->guest_r53 = 0; |
| vex_state->guest_r54 = 0; |
| vex_state->guest_r55 = 0; |
| |
| vex_state->guest_pc = 0; /* Program counter */ |
| |
| vex_state->guest_EMNOTE = 0; |
| vex_state->guest_CMSTART = 0; |
| |
| /* For clflush: record start and length of area to invalidate */ |
| vex_state->guest_CMSTART = 0; |
| vex_state->guest_CMLEN = 0; |
| |
| /* Used to record the unredirected guest address at the start of |
| a translation whose start has been redirected. By reading |
| this pseudo-register shortly afterwards, the translation can |
| find out what the corresponding no-redirection address was. |
| Note, this is only set for wrap-style redirects, not for |
| replace-style ones. */ |
| vex_state->guest_NRADDR = 0; |
| } |
| |
| /*-----------------------------------------------------------*/ |
| /*--- Describing the tilegx guest state, for the benefit ---*/ |
| /*--- of iropt and instrumenters. ---*/ |
| /*-----------------------------------------------------------*/ |
| |
| /* Figure out if any part of the guest state contained in minoff |
| .. maxoff requires precise memory exceptions. If in doubt return |
| True (but this is generates significantly slower code). |
| |
| We enforce precise exns for guest SP, PC. |
| */ |
| Bool guest_tilegx_state_requires_precise_mem_exns ( |
| Int minoff, Int maxoff, |
| VexRegisterUpdates pxControl) |
| { |
| Int sp_min = offsetof(VexGuestTILEGXState, guest_r54); |
| Int sp_max = sp_min + 8 - 1; |
| Int pc_min = offsetof(VexGuestTILEGXState, guest_pc); |
| Int pc_max = pc_min + 8 - 1; |
| |
| if (maxoff < sp_min || minoff > sp_max) { |
| /* no overlap with sp */ |
| if (pxControl == VexRegUpdSpAtMemAccess) |
| return False; /* We only need to check stack pointer. */ |
| } else { |
| return True; |
| } |
| |
| if (maxoff < pc_min || minoff > pc_max) { |
| /* no overlap with pc */ |
| } else { |
| return True; |
| } |
| |
| /* We appear to need precise updates of R52 in order to get proper |
| stacktraces from non-optimised code. */ |
| Int fp_min = offsetof(VexGuestTILEGXState, guest_r52); |
| Int fp_max = fp_min + 8 - 1; |
| |
| if (maxoff < fp_min || minoff > fp_max) { |
| /* no overlap with fp */ |
| } else { |
| return True; |
| } |
| |
| return False; |
| } |
| |
| VexGuestLayout tilegxGuest_layout = { |
| /* Total size of the guest state, in bytes. */ |
| .total_sizeB = sizeof(VexGuestTILEGXState), |
| /* Describe the stack pointer. */ |
| .offset_SP = offsetof(VexGuestTILEGXState, guest_r54), |
| .sizeof_SP = 8, |
| /* Describe the frame pointer. */ |
| .offset_FP = offsetof(VexGuestTILEGXState, guest_r52), |
| .sizeof_FP = 8, |
| /* Describe the instruction pointer. */ |
| .offset_IP = offsetof(VexGuestTILEGXState, guest_pc), |
| .sizeof_IP = 8, |
| /* Describe any sections to be regarded by Memcheck as |
| 'always-defined'. */ |
| .n_alwaysDefd = 8, |
| /* ? :( */ |
| .alwaysDefd = { |
| /* 0 */ ALWAYSDEFD(guest_r0), |
| /* 1 */ ALWAYSDEFD(guest_r1), |
| /* 2 */ ALWAYSDEFD(guest_EMNOTE), |
| /* 3 */ ALWAYSDEFD(guest_CMSTART), |
| /* 4 */ ALWAYSDEFD(guest_CMLEN), |
| /* 5 */ ALWAYSDEFD(guest_r52), |
| /* 6 */ ALWAYSDEFD(guest_r55), |
| /* 7 */ ALWAYSDEFD(guest_pc), |
| } |
| }; |
| |
| #ifdef __tilegx__ |
| ULong tilegx_dirtyhelper_gen ( ULong opc, |
| ULong rd0, ULong rd1, |
| ULong rd2, ULong rd3) |
| { |
| switch (opc) |
| { |
| case 0: |
| { |
| /* break point */ |
| switch (rd0) { |
| case 0x286a44ae90048fffULL: |
| asm (" bpt "); |
| break; |
| default: |
| vex_printf("unhandled \"bpt\": cins=%016llx\n", rd0); |
| |
| vassert(0); |
| return 0; |
| } |
| } |
| break; |
| case 28: |
| { |
| return __insn_addxsc(rd1, rd2); |
| } |
| break; |
| |
| case 150: |
| { |
| __insn_mf(); |
| return 0; |
| } |
| break; |
| |
| case 152: /* mm rd, ra, imm0, imm1 */ |
| { |
| ULong mask; |
| |
| if( rd2 <= rd3) |
| mask = (-1ULL << rd2) ^ ((-1ULL << rd3) << 1); |
| else |
| mask = (-1ULL << rd2) | (-1ULL >> (63 - rd3)); |
| |
| return (rd0 & mask) | (rd1 & (-1ULL ^ mask)); |
| } |
| break; |
| case 154: /* mtspr imm, ra */ |
| { |
| switch(rd0) |
| { |
| case 0x2785: |
| __insn_mtspr(0x2785, rd1); |
| break; |
| case 0x2780: |
| __insn_mtspr(0x2780, rd1); |
| break; |
| case 0x2708: |
| __insn_mtspr(0x2708, rd1); |
| break; |
| case 0x2580: |
| __insn_mtspr(0x2580, rd1); |
| break; |
| case 0x2581: |
| __insn_mtspr(0x2581, rd1); |
| break; |
| case 0x2709: // PASS |
| __insn_mtspr(0x2709, rd1); |
| break; |
| case 0x2707: // FAIL |
| __insn_mtspr(0x2707, rd1); |
| break; |
| case 0x2705: // DONE |
| __insn_mtspr(0x2705, rd1); |
| break; |
| |
| case 0x2870: // |
| |
| default: |
| vex_printf("opc=%d rd0=%llx rd1=%llx\n", |
| (int)opc, rd0, rd1); |
| vassert(0); |
| } |
| } |
| break; |
| |
| case 151: /* mfspr rd, imm */ |
| { |
| switch(rd1) |
| { |
| case 0x2785: // SIM_CTRL |
| return __insn_mfspr(0x2785); |
| break; |
| |
| case 0x2708: // ICS |
| return __insn_mfspr(0x2708); |
| break; |
| |
| case 0x2780: // CMPEXCH_VALUE |
| return __insn_mfspr(0x2780); |
| break; |
| |
| case 0x2781: // CYCLE |
| return __insn_mfspr(0x2781); |
| break; |
| |
| case 0x2709: // PASS |
| return __insn_mfspr(0x2709); |
| break; |
| |
| case 0x2707: // FAIL |
| return __insn_mfspr(0x2707); |
| break; |
| |
| case 0x2705: // DONE |
| return __insn_mfspr(0x2705); |
| break; |
| |
| case 0x2580: // EX_CONTEXT_0 |
| return __insn_mfspr(0x2580); |
| break; |
| |
| case 0x2581: // EX_CONTEXT_1 |
| return __insn_mfspr(0x2581); |
| break; |
| |
| default: |
| vex_printf("opc=%d rd0=%llx rd1=%llx\n", |
| (int)opc, rd0, rd1); |
| vassert(0); |
| } |
| } |
| break; |
| case 183: |
| { |
| return __insn_pcnt(rd1); |
| } |
| break; |
| case 184: |
| { |
| return __insn_revbits(rd1); |
| } |
| break; |
| case 185: /* revbytes rd, ra */ |
| { |
| return __insn_revbytes(rd1); |
| } |
| break; |
| |
| case 102: |
| return __insn_fsingle_add1(rd1, rd2); |
| break; |
| |
| case 103: |
| return __insn_fsingle_addsub2(rd0, rd1, rd2); |
| break; |
| |
| case 104: |
| return __insn_fsingle_mul1(rd1, rd2); |
| break; |
| |
| case 105: |
| return __insn_fsingle_mul2(rd1, rd2); |
| break; |
| |
| case 106: |
| return __insn_fsingle_pack1(rd1); |
| break; |
| |
| case 107: |
| return __insn_fsingle_pack2(rd1, rd2); |
| break; |
| |
| case 108: |
| return __insn_fsingle_sub1(rd1, rd2); |
| break; |
| |
| case 21: |
| switch (rd0) { |
| case 0x286a44ae90048fffULL: |
| asm ("{ moveli zero, 72 ; raise }"); |
| break; |
| default: |
| vex_printf("unhandled \"raise\": cins=%016llx\n", rd0); |
| __insn_ill(); |
| return 0; |
| } |
| break; |
| |
| case 64: |
| { |
| return __insn_cmul(rd1, rd2); |
| } |
| break; |
| case 65: |
| { |
| return __insn_cmula(rd0, rd1, rd2); |
| } |
| break; |
| case 66: |
| { |
| return __insn_cmulaf(rd0, rd1, rd2); |
| } |
| break; |
| case 67: |
| { |
| return __insn_cmulf(rd1, rd2); |
| } |
| break; |
| case 68: |
| { |
| return __insn_cmulfr(rd1, rd2); |
| } |
| break; |
| case 69: |
| { |
| return __insn_cmulh(rd1, rd2); |
| } |
| break; |
| case 70: |
| { |
| return __insn_cmulhr(rd1, rd2); |
| } |
| break; |
| case 71: |
| { |
| return __insn_crc32_32(rd1, rd2); |
| } |
| break; |
| case 72: |
| { |
| return __insn_crc32_8(rd1, rd2); |
| } |
| break; |
| case 75: |
| { |
| return __insn_dblalign2(rd1, rd2); |
| } |
| break; |
| case 76: |
| { |
| return __insn_dblalign4(rd1, rd2); |
| } |
| break; |
| case 77: |
| { |
| return __insn_dblalign6(rd1, rd2); |
| } |
| break; |
| case 78: |
| { |
| __insn_drain(); |
| return 0; |
| } |
| break; |
| case 79: |
| { |
| __insn_dtlbpr(rd0); |
| return 0; |
| } |
| break; |
| case 82: |
| { |
| return __insn_fdouble_add_flags(rd1, rd2); |
| } |
| break; |
| case 83: |
| { |
| return __insn_fdouble_addsub(rd0, rd1, rd2); |
| } |
| break; |
| case 84: |
| { |
| return __insn_fdouble_mul_flags(rd1, rd2); |
| } |
| break; |
| case 85: |
| { |
| return __insn_fdouble_pack1(rd1, rd2); |
| } |
| break; |
| case 86: |
| { |
| return __insn_fdouble_pack2(rd0, rd1, rd2); |
| } |
| break; |
| case 87: |
| { |
| return __insn_fdouble_sub_flags(rd1, rd2); |
| } |
| break; |
| case 88: |
| { |
| return __insn_fdouble_unpack_max(rd1, rd2); |
| } |
| break; |
| case 89: |
| { |
| return __insn_fdouble_unpack_min(rd1, rd2); |
| } |
| break; |
| |
| case 98: |
| { |
| __insn_finv(rd0); |
| return 0; |
| } |
| break; |
| case 99: |
| { |
| __insn_flush(rd0); |
| return 0; |
| } |
| break; |
| case 100: |
| { |
| __insn_flushwb(); |
| return 0; |
| } |
| break; |
| |
| case 109: |
| { |
| __insn_icoh((ULong *)rd0); |
| return 0; |
| } |
| break; |
| case 110: |
| { |
| __insn_ill(); |
| } |
| break; |
| case 111: |
| { |
| __insn_inv((ULong *)rd0); |
| return 0; |
| } |
| break; |
| |
| case 169: |
| { |
| return __insn_mula_hu_hu(rd0, rd1, rd2); |
| } |
| break; |
| case 170: |
| { |
| return __insn_mula_hu_ls(rd0, rd1, rd2); |
| } |
| break; |
| case 205: |
| { |
| return __insn_shufflebytes(rd0, rd1, rd2); |
| } |
| break; |
| case 224: |
| { |
| return __insn_subxsc(rd1, rd2); |
| } |
| break; |
| case 229: |
| { |
| return __insn_tblidxb0(rd0, rd1); |
| } |
| break; |
| case 230: |
| { |
| return __insn_tblidxb1(rd0, rd1); |
| } |
| break; |
| case 231: |
| { |
| return __insn_tblidxb2(rd0, rd1); |
| } |
| break; |
| case 232: |
| { |
| return __insn_tblidxb3(rd0, rd1); |
| } |
| break; |
| case 233: |
| { |
| return __insn_v1add(rd1, rd2); |
| } |
| break; |
| case 234: |
| { |
| return __insn_v1add(rd1, rd2); |
| } |
| break; |
| case 235: |
| { |
| return __insn_v1adduc(rd1, rd2); |
| } |
| break; |
| case 236: |
| { |
| return __insn_v1adiffu(rd1, rd2); |
| } |
| break; |
| case 237: |
| { |
| return __insn_v1avgu(rd1, rd2); |
| } |
| break; |
| |
| case 238: |
| { |
| return __insn_v1cmpeq(rd1, rd2); |
| } |
| break; |
| case 239: |
| { |
| return __insn_v1cmpeq(rd1, rd2); |
| } |
| break; |
| case 240: |
| { |
| return __insn_v1cmples(rd1, rd2); |
| } |
| break; |
| case 241: |
| { |
| return __insn_v1cmpleu(rd1, rd2); |
| } |
| break; |
| case 242: |
| { |
| return __insn_v1cmplts(rd1, rd2); |
| } |
| break; |
| case 243: |
| { |
| return __insn_v1cmplts(rd1, rd2); |
| } |
| break; |
| case 244: |
| { |
| return __insn_v1cmpltu(rd1, rd2); |
| } |
| break; |
| case 245: |
| { |
| return __insn_v1cmpltu(rd1, rd2); |
| } |
| break; |
| case 246: |
| { |
| return __insn_v1cmpne(rd1, rd2); |
| } |
| break; |
| case 247: |
| { |
| return __insn_v1ddotpu(rd1, rd2); |
| } |
| break; |
| case 248: |
| { |
| return __insn_v1ddotpua(rd0, rd1, rd2); |
| } |
| break; |
| case 249: |
| { |
| return __insn_v1ddotpus(rd1, rd2); |
| } |
| break; |
| case 250: |
| { |
| return __insn_v1ddotpusa(rd0, rd1, rd2); |
| } |
| break; |
| case 251: |
| { |
| return __insn_v1dotp(rd1, rd2); |
| } |
| break; |
| case 252: |
| { |
| return __insn_v1dotpa(rd0, rd1, rd2); |
| } |
| break; |
| case 253: |
| { |
| return __insn_v1dotpu(rd1, rd2); |
| } |
| break; |
| case 254: |
| { |
| return __insn_v1dotpua(rd0, rd1, rd2); |
| } |
| break; |
| case 255: |
| { |
| return __insn_v1dotpus(rd1, rd2); |
| } |
| break; |
| case 256: |
| { |
| return __insn_v1dotpusa(rd0, rd1, rd2); |
| } |
| break; |
| case 257: |
| { |
| return __insn_v1int_h(rd1, rd2); |
| } |
| break; |
| case 258: |
| { |
| return __insn_v1int_l(rd1, rd2); |
| } |
| break; |
| case 259: |
| { |
| return __insn_v1maxu(rd1, rd2); |
| } |
| break; |
| case 260: |
| { |
| return __insn_v1maxu(rd1, rd2); |
| } |
| break; |
| case 261: |
| { |
| return __insn_v1minu(rd1, rd2); |
| } |
| break; |
| case 262: |
| { |
| return __insn_v1minu(rd1, rd2); |
| } |
| break; |
| case 263: |
| { |
| return __insn_v1mnz(rd1, rd2); |
| } |
| break; |
| case 264: |
| { |
| return __insn_v1multu(rd1, rd2); |
| } |
| break; |
| case 265: |
| { |
| return __insn_v1mulu(rd1, rd2); |
| } |
| break; |
| case 266: |
| { |
| return __insn_v1mulus(rd1, rd2); |
| } |
| break; |
| case 267: |
| { |
| return __insn_v1mz(rd1, rd2); |
| } |
| break; |
| case 268: |
| { |
| return __insn_v1sadau(rd0, rd1, rd2); |
| } |
| break; |
| case 269: |
| { |
| return __insn_v1sadu(rd1, rd2); |
| } |
| break; |
| case 270: |
| { |
| return __insn_v1shl(rd1, rd2); |
| } |
| break; |
| case 271: |
| { |
| return __insn_v1shl(rd1, rd2); |
| } |
| break; |
| case 272: |
| { |
| return __insn_v1shrs(rd1, rd2); |
| } |
| break; |
| case 273: |
| { |
| return __insn_v1shrs(rd1, rd2); |
| } |
| break; |
| case 274: |
| { |
| return __insn_v1shru(rd1, rd2); |
| } |
| break; |
| case 275: |
| { |
| return __insn_v1shrui(rd1, rd2); |
| } |
| break; |
| case 276: |
| { |
| return __insn_v1sub(rd1, rd2); |
| } |
| break; |
| case 277: |
| { |
| return __insn_v1subuc(rd1, rd2); |
| } |
| break; |
| case 278: |
| { |
| return __insn_v2add(rd1, rd2); |
| } |
| break; |
| case 279: |
| { |
| return __insn_v2add(rd1, rd2); |
| } |
| break; |
| case 280: |
| { |
| return __insn_v2addsc(rd1, rd2); |
| } |
| break; |
| case 281: |
| { |
| return __insn_v2adiffs(rd1, rd2); |
| } |
| break; |
| case 282: |
| { |
| return __insn_v2avgs(rd1, rd2); |
| } |
| break; |
| case 283: |
| { |
| return __insn_v2cmpeq(rd1, rd2); |
| } |
| break; |
| case 284: |
| { |
| return __insn_v2cmpeq(rd1, rd2); |
| } |
| break; |
| case 285: |
| { |
| return __insn_v2cmples(rd1, rd2); |
| } |
| break; |
| case 286: |
| { |
| return __insn_v2cmpleu(rd1, rd2); |
| } |
| break; |
| case 287: |
| { |
| return __insn_v2cmplts(rd1, rd2); |
| } |
| break; |
| case 288: |
| { |
| return __insn_v2cmplts(rd1, rd2); |
| } |
| break; |
| case 289: |
| { |
| return __insn_v2cmpltu(rd1, rd2); |
| } |
| break; |
| case 290: |
| { |
| return __insn_v2cmpltu(rd1, rd2); |
| } |
| break; |
| case 291: |
| { |
| return __insn_v2cmpne(rd1, rd2); |
| } |
| break; |
| case 292: |
| { |
| return __insn_v2dotp(rd1, rd2); |
| } |
| break; |
| case 293: |
| { |
| return __insn_v2dotpa(rd0, rd1, rd2); |
| } |
| break; |
| case 294: |
| { |
| return __insn_v2int_h(rd1, rd2); |
| } |
| break; |
| case 295: |
| { |
| return __insn_v2int_l(rd1, rd2); |
| } |
| break; |
| case 296: |
| { |
| return __insn_v2maxs(rd1, rd2); |
| } |
| break; |
| case 297: |
| { |
| return __insn_v2maxs(rd1, rd2); |
| } |
| break; |
| case 298: |
| { |
| return __insn_v2mins(rd1, rd2); |
| } |
| break; |
| case 299: |
| { |
| return __insn_v2mins(rd1, rd2); |
| } |
| break; |
| case 300: |
| { |
| return __insn_v2mnz(rd1, rd2); |
| } |
| break; |
| case 301: |
| { |
| return __insn_v2mulfsc(rd1, rd2); |
| } |
| break; |
| case 302: |
| { |
| return __insn_v2muls(rd1, rd2); |
| } |
| break; |
| case 303: |
| { |
| return __insn_v2mults(rd1, rd2); |
| } |
| break; |
| case 304: |
| { |
| return __insn_v2mz(rd1, rd2); |
| } |
| break; |
| case 305: |
| { |
| return __insn_v2packh(rd1, rd2); |
| } |
| break; |
| case 306: |
| { |
| return __insn_v2packl(rd1, rd2); |
| } |
| break; |
| case 307: |
| { |
| return __insn_v2packuc(rd1, rd2); |
| } |
| break; |
| case 308: |
| { |
| return __insn_v2sadas(rd0, rd1, rd2); |
| } |
| break; |
| case 309: |
| { |
| return __insn_v2sadau(rd0, rd1, rd2); |
| } |
| break; |
| case 310: |
| { |
| return __insn_v2sads(rd1, rd2); |
| } |
| break; |
| case 311: |
| { |
| return __insn_v2sadu(rd1, rd2); |
| } |
| break; |
| case 312: |
| { |
| return __insn_v2shl(rd1, rd2); |
| } |
| break; |
| case 313: |
| { |
| return __insn_v2shl(rd1, rd2); |
| } |
| break; |
| case 314: |
| { |
| return __insn_v2shlsc(rd1, rd2); |
| } |
| break; |
| case 315: |
| { |
| return __insn_v2shrs(rd1, rd2); |
| } |
| break; |
| case 316: |
| { |
| return __insn_v2shrs(rd1, rd2); |
| } |
| break; |
| case 317: |
| { |
| return __insn_v2shru(rd1, rd2); |
| } |
| break; |
| case 318: |
| { |
| return __insn_v2shru(rd1, rd2); |
| } |
| break; |
| case 319: |
| { |
| return __insn_v2sub(rd1, rd2); |
| } |
| break; |
| case 320: |
| { |
| return __insn_v2subsc(rd1, rd2); |
| } |
| break; |
| case 321: |
| { |
| return __insn_v4add(rd1, rd2); |
| } |
| break; |
| case 322: |
| { |
| return __insn_v4addsc(rd1, rd2); |
| } |
| break; |
| case 323: |
| { |
| return __insn_v4int_h(rd1, rd2); |
| } |
| break; |
| case 324: |
| { |
| return __insn_v4int_l(rd1, rd2); |
| } |
| break; |
| case 325: |
| { |
| return __insn_v4packsc(rd1, rd2); |
| } |
| break; |
| case 326: |
| { |
| return __insn_v4shl(rd1, rd2); |
| } |
| break; |
| case 327: |
| { |
| return __insn_v4shlsc(rd1, rd2); |
| } |
| break; |
| case 328: |
| { |
| return __insn_v4shrs(rd1, rd2); |
| } |
| break; |
| case 329: |
| { |
| return __insn_v4shru(rd1, rd2); |
| } |
| break; |
| case 330: |
| { |
| return __insn_v4sub(rd1, rd2); |
| } |
| break; |
| case 331: |
| { |
| return __insn_v4subsc(rd1, rd2); |
| } |
| break; |
| |
| default: |
| vex_printf("opc=%d rd0=%llx rd1=%llx\n", |
| (int)opc, rd0, rd1); |
| vassert(0); |
| } |
| } |
| #else |
| ULong tilegx_dirtyhelper_gen ( ULong opc, |
| ULong rd0, ULong rd1, |
| ULong rd2, ULong rd3 ) |
| { |
| vex_printf("NOT a TILEGX platform"); |
| return 0; |
| } |
| #endif /* __tilegx__ */ |
| |
| /*---------------------------------------------------------------*/ |
| /*--- end guest_tilegx_helpers.c ---*/ |
| /*---------------------------------------------------------------*/ |