Revision 0db921e6
b/tcg/s390/tcg-target.c | ||
---|---|---|
35 | 35 |
#define USE_LONG_BRANCHES 0 |
36 | 36 |
|
37 | 37 |
#define TCG_CT_CONST_32 0x0100 |
38 |
#define TCG_CT_CONST_NEG 0x0200 |
|
39 |
#define TCG_CT_CONST_ADDI 0x0400 |
|
40 | 38 |
#define TCG_CT_CONST_MULI 0x0800 |
41 | 39 |
#define TCG_CT_CONST_ORI 0x2000 |
42 | 40 |
#define TCG_CT_CONST_XORI 0x4000 |
... | ... | |
90 | 88 |
RIL_OIHF = 0xc00c, |
91 | 89 |
RIL_OILF = 0xc00d, |
92 | 90 |
RIL_SLFI = 0xc205, |
91 |
RIL_SLGFI = 0xc204, |
|
93 | 92 |
RIL_XIHF = 0xc006, |
94 | 93 |
RIL_XILF = 0xc007, |
95 | 94 |
|
... | ... | |
191 | 190 |
RXY_AY = 0xe35a, |
192 | 191 |
RXY_CG = 0xe320, |
193 | 192 |
RXY_CY = 0xe359, |
193 |
RXY_LAY = 0xe371, |
|
194 | 194 |
RXY_LB = 0xe376, |
195 | 195 |
RXY_LG = 0xe304, |
196 | 196 |
RXY_LGB = 0xe377, |
... | ... | |
217 | 217 |
RX_A = 0x5a, |
218 | 218 |
RX_C = 0x59, |
219 | 219 |
RX_L = 0x58, |
220 |
RX_LA = 0x41, |
|
220 | 221 |
RX_LH = 0x48, |
221 | 222 |
RX_ST = 0x50, |
222 | 223 |
RX_STC = 0x42, |
... | ... | |
405 | 406 |
tcg_regset_clear(ct->u.regs); |
406 | 407 |
tcg_regset_set_reg(ct->u.regs, TCG_REG_R3); |
407 | 408 |
break; |
408 |
case 'N': /* force immediate negate */ |
|
409 |
ct->ct |= TCG_CT_CONST_NEG; |
|
410 |
break; |
|
411 | 409 |
case 'W': /* force 32-bit ("word") immediate */ |
412 | 410 |
ct->ct |= TCG_CT_CONST_32; |
413 | 411 |
break; |
414 |
case 'I': |
|
415 |
ct->ct |= TCG_CT_CONST_ADDI; |
|
416 |
break; |
|
417 | 412 |
case 'K': |
418 | 413 |
ct->ct |= TCG_CT_CONST_MULI; |
419 | 414 |
break; |
... | ... | |
529 | 524 |
} |
530 | 525 |
|
531 | 526 |
/* Handle the modifiers. */ |
532 |
if (ct & TCG_CT_CONST_NEG) { |
|
533 |
val = -val; |
|
534 |
} |
|
535 | 527 |
if (ct & TCG_CT_CONST_32) { |
536 | 528 |
val = (int32_t)val; |
537 | 529 |
} |
538 | 530 |
|
539 | 531 |
/* The following are mutually exclusive. */ |
540 |
if (ct & TCG_CT_CONST_ADDI) { |
|
541 |
/* Immediates that may be used with add. If we have the |
|
542 |
extended-immediates facility then we have ADD IMMEDIATE |
|
543 |
with signed and unsigned 32-bit, otherwise we have only |
|
544 |
ADD HALFWORD IMMEDIATE with a signed 16-bit. */ |
|
545 |
if (facilities & FACILITY_EXT_IMM) { |
|
546 |
return val == (int32_t)val || val == (uint32_t)val; |
|
547 |
} else { |
|
548 |
return val == (int16_t)val; |
|
549 |
} |
|
550 |
} else if (ct & TCG_CT_CONST_MULI) { |
|
532 |
if (ct & TCG_CT_CONST_MULI) { |
|
551 | 533 |
/* Immediates that may be used with multiply. If we have the |
552 | 534 |
general-instruction-extensions, then we have MULTIPLY SINGLE |
553 | 535 |
IMMEDIATE with a signed 32-bit, otherwise we have only |
... | ... | |
927 | 909 |
tcg_out_insn(s, RRE, LLGFR, dest, src); |
928 | 910 |
} |
929 | 911 |
|
930 |
static inline void tgen32_addi(TCGContext *s, TCGReg dest, int32_t val) |
|
931 |
{ |
|
932 |
if (val == (int16_t)val) { |
|
933 |
tcg_out_insn(s, RI, AHI, dest, val); |
|
934 |
} else { |
|
935 |
tcg_out_insn(s, RIL, AFI, dest, val); |
|
936 |
} |
|
937 |
} |
|
938 |
|
|
939 |
static inline void tgen64_addi(TCGContext *s, TCGReg dest, int64_t val) |
|
940 |
{ |
|
941 |
if (val == (int16_t)val) { |
|
942 |
tcg_out_insn(s, RI, AGHI, dest, val); |
|
943 |
} else if (val == (int32_t)val) { |
|
944 |
tcg_out_insn(s, RIL, AGFI, dest, val); |
|
945 |
} else if (val == (uint32_t)val) { |
|
946 |
tcg_out_insn(s, RIL, ALGFI, dest, val); |
|
947 |
} else { |
|
948 |
tcg_abort(); |
|
949 |
} |
|
950 |
|
|
951 |
} |
|
952 |
|
|
953 | 912 |
/* Accept bit patterns like these: |
954 | 913 |
0....01....1 |
955 | 914 |
1....10....0 |
... | ... | |
1640 | 1599 |
const TCGArg *args, const int *const_args) |
1641 | 1600 |
{ |
1642 | 1601 |
S390Opcode op; |
1602 |
TCGArg a0, a1, a2; |
|
1643 | 1603 |
|
1644 | 1604 |
switch (opc) { |
1645 | 1605 |
case INDEX_op_exit_tb: |
... | ... | |
1715 | 1675 |
break; |
1716 | 1676 |
|
1717 | 1677 |
case INDEX_op_add_i32: |
1678 |
a0 = args[0], a1 = args[1], a2 = (int32_t)args[2]; |
|
1718 | 1679 |
if (const_args[2]) { |
1719 |
tgen32_addi(s, args[0], args[2]); |
|
1680 |
do_addi_32: |
|
1681 |
if (a0 == a1) { |
|
1682 |
if (a2 == (int16_t)a2) { |
|
1683 |
tcg_out_insn(s, RI, AHI, a0, a2); |
|
1684 |
break; |
|
1685 |
} |
|
1686 |
if (facilities & FACILITY_EXT_IMM) { |
|
1687 |
tcg_out_insn(s, RIL, AFI, a0, a2); |
|
1688 |
break; |
|
1689 |
} |
|
1690 |
} |
|
1691 |
tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2); |
|
1692 |
} else if (a0 == a1) { |
|
1693 |
tcg_out_insn(s, RR, AR, a0, a2); |
|
1720 | 1694 |
} else { |
1721 |
tcg_out_insn(s, RR, AR, args[0], args[2]);
|
|
1695 |
tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
|
|
1722 | 1696 |
} |
1723 | 1697 |
break; |
1724 | 1698 |
case INDEX_op_sub_i32: |
1699 |
a0 = args[0], a1 = args[1], a2 = (int32_t)args[2]; |
|
1725 | 1700 |
if (const_args[2]) { |
1726 |
tgen32_addi(s, args[0], -args[2]); |
|
1727 |
} else { |
|
1728 |
tcg_out_insn(s, RR, SR, args[0], args[2]); |
|
1701 |
a2 = -a2; |
|
1702 |
goto do_addi_32; |
|
1729 | 1703 |
} |
1704 |
tcg_out_insn(s, RR, SR, args[0], args[2]); |
|
1730 | 1705 |
break; |
1731 | 1706 |
|
1732 | 1707 |
case INDEX_op_and_i32: |
... | ... | |
1920 | 1895 |
break; |
1921 | 1896 |
|
1922 | 1897 |
case INDEX_op_add_i64: |
1898 |
a0 = args[0], a1 = args[1], a2 = args[2]; |
|
1923 | 1899 |
if (const_args[2]) { |
1924 |
tgen64_addi(s, args[0], args[2]); |
|
1900 |
do_addi_64: |
|
1901 |
if (a0 == a1) { |
|
1902 |
if (a2 == (int16_t)a2) { |
|
1903 |
tcg_out_insn(s, RI, AGHI, a0, a2); |
|
1904 |
break; |
|
1905 |
} |
|
1906 |
if (facilities & FACILITY_EXT_IMM) { |
|
1907 |
if (a2 == (int32_t)a2) { |
|
1908 |
tcg_out_insn(s, RIL, AGFI, a0, a2); |
|
1909 |
break; |
|
1910 |
} else if (a2 == (uint32_t)a2) { |
|
1911 |
tcg_out_insn(s, RIL, ALGFI, a0, a2); |
|
1912 |
break; |
|
1913 |
} else if (-a2 == (uint32_t)-a2) { |
|
1914 |
tcg_out_insn(s, RIL, SLGFI, a0, -a2); |
|
1915 |
break; |
|
1916 |
} |
|
1917 |
} |
|
1918 |
} |
|
1919 |
tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2); |
|
1920 |
} else if (a0 == a1) { |
|
1921 |
tcg_out_insn(s, RRE, AGR, a0, a2); |
|
1925 | 1922 |
} else { |
1926 |
tcg_out_insn(s, RRE, AGR, args[0], args[2]);
|
|
1923 |
tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
|
|
1927 | 1924 |
} |
1928 | 1925 |
break; |
1929 | 1926 |
case INDEX_op_sub_i64: |
1927 |
a0 = args[0], a1 = args[1], a2 = args[2]; |
|
1930 | 1928 |
if (const_args[2]) { |
1931 |
tgen64_addi(s, args[0], -args[2]); |
|
1929 |
a2 = -a2; |
|
1930 |
goto do_addi_64; |
|
1932 | 1931 |
} else { |
1933 | 1932 |
tcg_out_insn(s, RRE, SGR, args[0], args[2]); |
1934 | 1933 |
} |
... | ... | |
2103 | 2102 |
{ INDEX_op_st16_i32, { "r", "r" } }, |
2104 | 2103 |
{ INDEX_op_st_i32, { "r", "r" } }, |
2105 | 2104 |
|
2106 |
{ INDEX_op_add_i32, { "r", "0", "rWI" } },
|
|
2107 |
{ INDEX_op_sub_i32, { "r", "0", "rWNI" } },
|
|
2105 |
{ INDEX_op_add_i32, { "r", "r", "ri" } },
|
|
2106 |
{ INDEX_op_sub_i32, { "r", "0", "ri" } },
|
|
2108 | 2107 |
{ INDEX_op_mul_i32, { "r", "0", "rK" } }, |
2109 | 2108 |
|
2110 | 2109 |
{ INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } }, |
... | ... | |
2167 | 2166 |
{ INDEX_op_st32_i64, { "r", "r" } }, |
2168 | 2167 |
{ INDEX_op_st_i64, { "r", "r" } }, |
2169 | 2168 |
|
2170 |
{ INDEX_op_add_i64, { "r", "0", "rI" } },
|
|
2171 |
{ INDEX_op_sub_i64, { "r", "0", "rNI" } },
|
|
2169 |
{ INDEX_op_add_i64, { "r", "r", "ri" } },
|
|
2170 |
{ INDEX_op_sub_i64, { "r", "0", "ri" } },
|
|
2172 | 2171 |
{ INDEX_op_mul_i64, { "r", "0", "rK" } }, |
2173 | 2172 |
|
2174 | 2173 |
{ INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } }, |
Also available in: Unified diff