Revision 116348de

b/tcg/mips/tcg-target.c
270 270

  
271 271
/* instruction opcodes */
272 272
enum {
273
    OPC_SPECIAL  = 0x00 << 26,
274 273
    OPC_BEQ      = 0x04 << 26,
275 274
    OPC_BNE      = 0x05 << 26,
276 275
    OPC_ADDIU    = 0x09 << 26,
......
289 288
    OPC_SB       = 0x28 << 26,
290 289
    OPC_SH       = 0x29 << 26,
291 290
    OPC_SW       = 0x2B << 26,
291

  
292
    OPC_SPECIAL  = 0x00 << 26,
292 293
    OPC_SLL      = OPC_SPECIAL | 0x00,
293 294
    OPC_SRL      = OPC_SPECIAL | 0x02,
294 295
    OPC_SRA      = OPC_SPECIAL | 0x03,
......
311 312
    OPC_NOR      = OPC_SPECIAL | 0x27,
312 313
    OPC_SLT      = OPC_SPECIAL | 0x2A,
313 314
    OPC_SLTU     = OPC_SPECIAL | 0x2B,
315

  
316
    OPC_SPECIAL3 = 0x1f << 26,
317
    OPC_SEB      = OPC_SPECIAL3 | 0x420,
318
    OPC_SEH      = OPC_SPECIAL3 | 0x620,
314 319
};
315 320

  
316 321
/*
......
441 446
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
442 447
}
443 448

  
449
static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
450
{
451
#ifdef _MIPS_ARCH_MIPS32R2
452
    tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
453
#else
454
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
455
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
456
#endif
457
}
458

  
459
static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
460
{
461
#ifdef _MIPS_ARCH_MIPS32R2
462
    tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
463
#else
464
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
465
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
466
#endif
467
}
468

  
444 469
static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
445 470
                              int arg1, tcg_target_long arg2)
446 471
{
......
838 863
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
839 864
        break;
840 865
    case 0 | 4:
841
        tcg_out_opc_sa(s, OPC_SLL, TCG_REG_V0, TCG_REG_V0, 24);
842
        tcg_out_opc_sa(s, OPC_SRA, data_reg1, TCG_REG_V0, 24);
866
        tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
843 867
        break;
844 868
    case 1:
845 869
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
846 870
        break;
847 871
    case 1 | 4:
848
        tcg_out_opc_sa(s, OPC_SLL, TCG_REG_V0, TCG_REG_V0, 16);
849
        tcg_out_opc_sa(s, OPC_SRA, data_reg1, TCG_REG_V0, 16);
872
        tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
850 873
        break;
851 874
    case 2:
852 875
        tcg_out_mov(s, data_reg1, TCG_REG_V0);
......
1149 1172
        break;
1150 1173

  
1151 1174
    case INDEX_op_ld8u_i32:
1152
	tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1175
        tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1153 1176
        break;
1154 1177
    case INDEX_op_ld8s_i32:
1155 1178
        tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
......
1293 1316
        }
1294 1317
        break;
1295 1318

  
1319
    case INDEX_op_ext8s_i32:
1320
        tcg_out_ext8s(s, args[0], args[1]);
1321
        break;
1322
    case INDEX_op_ext16s_i32:
1323
        tcg_out_ext16s(s, args[0], args[1]);
1324
        break;
1325

  
1296 1326
    case INDEX_op_brcond_i32:
1297 1327
        tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1298 1328
        break;
......
1380 1410
    { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
1381 1411
    { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
1382 1412

  
1413
    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1414
    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1415

  
1383 1416
    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1384 1417
    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1385 1418
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
b/tcg/mips/tcg-target.h
82 82
#define TCG_TARGET_HAS_not_i32
83 83
#define TCG_TARGET_HAS_nor_i32
84 84
#undef TCG_TARGET_HAS_rot_i32
85
#undef TCG_TARGET_HAS_ext8s_i32
86
#undef TCG_TARGET_HAS_ext16s_i32
85
#define TCG_TARGET_HAS_ext8s_i32
86
#define TCG_TARGET_HAS_ext16s_i32
87 87
#undef TCG_TARGET_HAS_bswap32_i32
88 88
#undef TCG_TARGET_HAS_bswap16_i32
89 89
#undef TCG_TARGET_HAS_andc_i32

Also available in: Unified diff