OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 if (is_uint16(src.imm32_) && s == LeaveCC) { | 139 if (is_uint16(src.imm32_) && s == LeaveCC) { |
140 mov_imm_t3(dst, src, s, cond); | 140 mov_imm_t3(dst, src, s, cond); |
141 return; | 141 return; |
142 } else { | 142 } else { |
143 uint32_t i, imm3, imm8; | 143 uint32_t i, imm3, imm8; |
144 if (thumb_expand_imm(src.imm32_, &i, &imm3, &imm8) && | 144 if (thumb_expand_imm(src.imm32_, &i, &imm3, &imm8) && |
145 !src.must_output_reloc_info(this)) { | 145 !src.must_output_reloc_info(this)) { |
146 mov_imm_t2(dst, s, cond, i, imm3, imm8); | 146 mov_imm_t2(dst, s, cond, i, imm3, imm8); |
147 return; | 147 return; |
148 } else { | 148 } else { |
149 // TODO(rkrithiv): perform 32-bit imm move | 149 move_32_bit_immediate_thumb(dst, s, src, cond); |
150 UNREACHABLE(); | |
151 return; | 150 return; |
152 } | 151 } |
153 } | 152 } |
154 } | 153 } |
155 } else { | 154 } else { |
156 // Register. | 155 // Register. |
157 if (src.rs_.is_valid() || (!src.rs_.is_valid() && src.shift_imm_ != 0)) { | 156 if (src.rs_.is_valid() || (!src.rs_.is_valid() && src.shift_imm_ != 0)) { |
158 switch (src.shift_op_) { | 157 switch (src.shift_op_) { |
159 case LSL: lsl_thumb(dst, src, s, cond); | 158 case LSL: lsl_thumb(dst, src, s, cond); |
160 return; | 159 return; |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 } | 700 } |
702 mask |= 4; | 701 mask |= 4; |
703 emit16(11*B12 | 15*B8 | (c << 4) | mask); | 702 emit16(11*B12 | 15*B8 | (c << 4) | mask); |
704 } else { | 703 } else { |
705 ASSERT(num_instr == 1); | 704 ASSERT(num_instr == 1); |
706 mask = 8; | 705 mask = 8; |
707 emit16(11*B12 | 15*B8 | (c << 4) | mask); | 706 emit16(11*B12 | 15*B8 | (c << 4) | mask); |
708 } | 707 } |
709 } | 708 } |
710 | 709 |
| 710 |
| 711 void Assembler::b_thumb(int branch_offset, Condition cond) { |
| 712 int imm = branch_offset >> 1; |
| 713 if (cond == al) { |
| 714 ASSERT(is_int24(imm)); |
| 715 emit32(thumb32_mode4(B_32_4) | thumb32_sign_extend_imm24(imm)); |
| 716 return; |
| 717 } else { |
| 718 uint32_t cond_thumb = (cond >> 28) & 0xF; |
| 719 ASSERT(is_int20(imm)); |
| 720 uint32_t imm11 = imm & 0x7ff; |
| 721 uint32_t imm6 = (imm >> 11) & 0x3f; |
| 722 uint32_t j1 = (imm >> 17) & 1; |
| 723 uint32_t j2 = (imm >> 18) & 1; |
| 724 uint32_t s = (imm >> 19) & 1; |
| 725 emit32(thumb32_mode4(B_32_3) | s*BH10 | cond_thumb*BH6 | |
| 726 imm6*BH0 | j1*B13 | j2*B11 | imm11); |
| 727 return; |
| 728 } |
| 729 UNREACHABLE(); |
| 730 } |
| 731 |
| 732 |
| 733 // from ldr_thumb_reg |
| 734 bool Assembler::fits_thumb16_mode_4_1(Register reg, const MemOperand& op) { |
| 735 return (is_uint3(op.rm().code()) && |
| 736 is_uint3(op.rn().code()) && |
| 737 is_uint3(reg.code()) && |
| 738 op.shift_imm_ == 0); |
| 739 } |
| 740 |
| 741 |
| 742 // other than 4_1 and 4_5 |
| 743 bool Assembler::fits_thumb16_mode_4(Register reg, const MemOperand& op) { |
| 744 // imm5, rn 3, rt 3 |
| 745 return (is_uint5(op.offset_) && |
| 746 are_low_reg(reg, op.rn_)); |
| 747 } |
| 748 |
| 749 |
| 750 bool Assembler::fits_thumb16_mode_4_5(Register reg, const MemOperand& op) { |
| 751 // Rt 3, imm8 (note: imm8:'00' so >> 2) |
| 752 return (is_uint8(op.offset() >> 2) && |
| 753 op.rn_.code() == 13 && |
| 754 is_low_reg(reg)); |
| 755 } |
| 756 |
| 757 |
| 758 // A6.3.7 see A8-118 immediate |
| 759 // A6.3.7 see A8-124 register |
| 760 // A6.3.7 see A8-122 literal |
| 761 // A6.2.4 see A8-124 reg |
| 762 // A6.2.4 see A8-124 reg |
| 763 // mode_4_2, pass opB // mode4 sets opA , param sets opB |
| 764 void Assembler::ldr_thumb_immediate(Register dst, const MemOperand& src) { |
| 765 if ((src.offset_ & 3) == 0 && src.am_ == Offset) { |
| 766 uint32_t offset = src.offset_ >> 2; |
| 767 if (fits_thumb16_mode_4(dst, src)) { |
| 768 // Encoding T1 (immediate) - 16 bit // mode_4_2 |
| 769 // emit16(/* imm5@6 Rn@3 Rt */); // LDR_IMM_1 |
| 770 emit16(thumb16_mode4_2(LDR_IMM_1) | |
| 771 thumb16_2lowreg_imm5_encoding(dst, src.rn_, offset)); |
| 772 return; |
| 773 } else if (fits_thumb16_mode_4_5(dst, src)) { |
| 774 // Encoding T2 (immediate) - 16 bit // mode_4_5, pass opB |
| 775 emit16(thumb16_mode4_5(LDR_IMM_2) | |
| 776 thumb16_lowreg_imm8_encoding(dst, offset)); |
| 777 return; |
| 778 } |
| 779 } |
| 780 if ((is_uint12(src.offset_) && src.offset_ >= 0 && src.am_ == Offset) || |
| 781 (src.rn_.code() == 15 && (is_uint12(src.offset_) || |
| 782 is_uint12(-src.offset_)))) { |
| 783 // Encoding T3 (immediate) - 32 bit |
| 784 emit32(thumb32_mode7(LDR_32_IMM3) | |
| 785 thumb32_2reg_zero_extend_imm12(dst, src)); |
| 786 return; |
| 787 } else if (is_uint8(src.offset_) || is_uint8(-src.offset_)) { |
| 788 // Encoding T4 (immediate) - 32 bit |
| 789 emit32(thumb32_mode7(LDR_32_IMM4) | |
| 790 thumb32_2reg_zero_extend_imm8(dst, src)); |
| 791 return; |
| 792 } |
| 793 mov_thumb(ip, Operand(src.offset_), LeaveCC, al); |
| 794 ldr_thumb(dst, MemOperand(src.rn_, ip, src.am_)); |
| 795 } |
| 796 |
| 797 |
| 798 void Assembler::ldr_thumb_register(Register dst, const MemOperand& src) { |
| 799 if (fits_thumb16_mode_4_1(dst, src)) { |
| 800 // Encoding T1 (register) - 16 bit |
| 801 emit16(thumb16_mode4_1(LDR_REG_1) | thumb16_3lowreg_encoding(dst, src)); |
| 802 return; |
| 803 } else { |
| 804 // Encoding T2 (register) - 32 bit |
| 805 emit32(thumb32_mode7(LDR_32_REG) | thumb32_3reg_lsl(dst, src)); |
| 806 return; |
| 807 } |
| 808 UNREACHABLE(); |
| 809 } |
| 810 |
| 811 |
| 812 void Assembler::ldr_thumb(Register dst, const MemOperand& src) { |
| 813 if (!src.rm_.is_valid()) { |
| 814 // Immediate. |
| 815 ldr_thumb_immediate(dst, src) ; |
| 816 return; |
| 817 } else { |
| 818 // Register |
| 819 ldr_thumb_register(dst, src); |
| 820 return; |
| 821 } |
| 822 UNREACHABLE(); |
| 823 } |
| 824 |
| 825 |
| 826 void Assembler::str_thumb_register(Register src, const MemOperand& dst) { |
| 827 if (fits_thumb16_mode_4_1(src, dst)) { |
| 828 // Encoding T1 (register) - 16 bit |
| 829 // Rm Rn Rt |
| 830 emit16(thumb16_mode4_1(STR_REG) | thumb16_3lowreg_encoding(src, dst)); |
| 831 return; |
| 832 } else if (dst.shift_op_ == LSL && is_uint2(dst.shift_imm_)) { |
| 833 // Encoding T2 (register) - 32 bit |
| 834 // Rn Rt imm2 Rm |
| 835 emit32(thumb32_mode10(STR_32_REG) | thumb32_3reg_lsl(src, dst)); |
| 836 return; |
| 837 } |
| 838 UNREACHABLE(); |
| 839 } |
| 840 |
| 841 |
| 842 void Assembler::str_thumb_immediate(Register src, const MemOperand& dst) { |
| 843 if (((dst.offset_ & 3) == 0) && dst.am_ == Offset) { |
| 844 // try 16-bit |
| 845 uint32_t offset = dst.offset_ >> 2; |
| 846 if (fits_thumb16_mode_4(src, dst)) { |
| 847 // Encoding T1 (immediate) - 16 bit -NOTE: imm5/Rn/Rt - Rt Is SRC, |
| 848 // Rn imm5 in MemOp |
| 849 // mode_4_2, pass opB |
| 850 // imm5 Rn Rt |
| 851 emit16(thumb16_mode4_2(STR_IMM_1) | |
| 852 thumb16_2lowreg_imm5_encoding(src, dst.rn_, offset)); |
| 853 return; |
| 854 } else if (fits_thumb16_mode_4_5(src, dst)) { |
| 855 // Encoding T2 (immediate) - 16 bit |
| 856 // mode_4_5, pass opB; Rt imm8 |
| 857 emit16(thumb16_mode4_5(STR_IMM_2) | |
| 858 thumb16_lowreg_imm8_encoding(src, offset)); |
| 859 return; |
| 860 } |
| 861 } |
| 862 // try 32-bit |
| 863 if (is_uint12(dst.offset_) && dst.am_ == Offset) { |
| 864 // Encoding T3 (immediate) - 32 bit |
| 865 // Rn Rt imm12 |
| 866 emit32(thumb32_mode10(STR_32_IMM2) | |
| 867 thumb32_2reg_zero_extend_imm12(src, dst)); |
| 868 return; |
| 869 } else if (is_uint8(dst.offset_) || is_uint8(-dst.offset_)) { |
| 870 // Encoding T4 (immediate) - 32 bit |
| 871 // Rn Rt immm8 |
| 872 emit32(thumb32_mode10(STR_32_IMM3) | |
| 873 thumb32_2reg_zero_extend_imm8(src, dst)); |
| 874 return; |
| 875 } |
| 876 mov_thumb(ip, Operand(dst.offset_), LeaveCC, al); |
| 877 str_thumb(src, MemOperand(dst.rn_, ip, dst.am_)); |
| 878 } |
| 879 |
| 880 |
| 881 void Assembler::str_thumb(Register src, const MemOperand& dst) { |
| 882 if (!dst.rm_.is_valid()) { |
| 883 // Immediate. |
| 884 str_thumb_immediate(src, dst) ; |
| 885 return; |
| 886 } else { |
| 887 // Register. |
| 888 str_thumb_register(src, dst) ; |
| 889 return; |
| 890 } |
| 891 UNREACHABLE(); |
| 892 } |
| 893 |
| 894 |
| 895 void Assembler::ldrb_thumb_immediate(Register dst, const MemOperand& src) { |
| 896 if (fits_thumb16_mode_4(dst, src)) { |
| 897 emit16(thumb16_mode4_3(LDRB_IMM) | |
| 898 thumb16_2lowreg_imm5_encoding(dst, src.rn_, src.offset_)); |
| 899 return; |
| 900 } else if (src.offset_ >= 0 && src.am_ == Offset && is_uint12(src.offset_)) { |
| 901 emit32(thumb32_mode9(LDRB_32_IMM2) | |
| 902 thumb32_2reg_zero_extend_imm12(dst, src)); |
| 903 return; |
| 904 } else if (is_uint8(src.offset_) || is_uint8(-src.offset_)) { |
| 905 emit32(thumb32_mode9(LDRB_32_IMM3) | |
| 906 thumb32_2reg_zero_extend_imm8(dst, src)); |
| 907 return; |
| 908 } |
| 909 mov_thumb(ip, Operand(src.offset_), LeaveCC, al); |
| 910 ldrb_thumb(dst, MemOperand(src.rn_, ip, src.am_)); |
| 911 } |
| 912 |
| 913 |
| 914 void Assembler::ldrb_thumb_register(Register dst, const MemOperand& src) { |
| 915 if (fits_thumb16_mode_4_1(dst, src)) { |
| 916 // Encoding T1 (register) - 16 bit |
| 917 emit16(thumb16_mode4_1(LDRB_REG) | thumb16_3lowreg_encoding(dst, src)); |
| 918 return; |
| 919 } else { |
| 920 // Encoding T2 (register) - 32 bit |
| 921 emit32(thumb32_mode9(LDRB_32_REG) | thumb32_3reg_lsl(dst, src)); |
| 922 return; |
| 923 } |
| 924 UNREACHABLE(); |
| 925 } |
| 926 |
| 927 |
| 928 void Assembler::ldrb_thumb(Register dst, const MemOperand& src) { |
| 929 if (!src.rm_.is_valid()) { |
| 930 // Immediate. |
| 931 ldrb_thumb_immediate(dst, src) ; |
| 932 return; |
| 933 } else { |
| 934 // Register. |
| 935 ldrb_thumb_register(dst, src) ; |
| 936 return; |
| 937 } |
| 938 UNREACHABLE(); |
| 939 } |
| 940 |
| 941 |
| 942 void Assembler::strb_thumb_immediate(Register src, const MemOperand& dst) { |
| 943 if (fits_thumb16_mode_4(src, dst)) { |
| 944 emit16(thumb16_mode4_3(STRB_IMM) | |
| 945 thumb16_2lowreg_imm5_encoding(src, dst.rn_, dst.offset_)); |
| 946 return; |
| 947 } else if (dst.offset_ >= 0 && dst.am_ == Offset && is_uint12(dst.offset_)) { |
| 948 emit32(thumb32_mode10(STRB_32_IMM2) | |
| 949 thumb32_2reg_zero_extend_imm12(src, dst)); |
| 950 return; |
| 951 } else if (is_uint8(dst.offset_) || is_uint8(-dst.offset_)) { |
| 952 emit32(thumb32_mode10(STRB_32_IMM3) | |
| 953 thumb32_2reg_zero_extend_imm8(src, dst)); |
| 954 return; |
| 955 } |
| 956 mov_thumb(ip, Operand(dst.offset_), LeaveCC, al); |
| 957 strb_thumb(src, MemOperand(dst.rn_, ip, dst.am_)); |
| 958 } |
| 959 |
| 960 |
| 961 void Assembler::strb_thumb_register(Register src, const MemOperand& dst) { |
| 962 if (fits_thumb16_mode_4_1(src, dst)) { |
| 963 // Encoding T1 (register) - 16 bit |
| 964 emit16(thumb16_mode4_1(STRB_REG) | thumb16_3lowreg_encoding(src, dst)); |
| 965 return; |
| 966 } else if (dst.shift_op_ == LSR) { |
| 967 ASSERT(dst.rn_.code() != ip.code()); |
| 968 add_thumb(ip, dst.rn_, |
| 969 Operand(dst.rm_, dst.shift_op_, dst.shift_imm_), LeaveCC, al); |
| 970 strb_thumb(src, MemOperand(ip)); |
| 971 return; |
| 972 } else { |
| 973 // Encoding T2 (register) - 32 bit |
| 974 // Rn Rt imm2 Rm |
| 975 emit32(thumb32_mode10(STRB_32_REG) | thumb32_3reg_lsl(src, dst)); |
| 976 return; |
| 977 } |
| 978 UNREACHABLE(); |
| 979 } |
| 980 |
| 981 |
| 982 void Assembler::strb_thumb(Register src, const MemOperand& dst) { |
| 983 if (!dst.rm_.is_valid()) { |
| 984 // Immediate. |
| 985 strb_thumb_immediate(src, dst) ; |
| 986 return; |
| 987 } else { |
| 988 // Register. |
| 989 strb_thumb_register(src, dst) ; |
| 990 return; |
| 991 } |
| 992 UNREACHABLE(); |
| 993 } |
| 994 |
| 995 |
| 996 void Assembler::ldrh_thumb_immediate(Register dst, const MemOperand& src) { |
| 997 if (fits_thumb16_mode_4(dst, src) && (src.offset_ & 1) == 0) { |
| 998 emit16(thumb16_mode4_4(LDRH_IMM) | |
| 999 thumb16_2lowreg_imm5_encoding(dst, src.rn_, (src.offset_ >> 1))); |
| 1000 return; |
| 1001 } else if (src.offset_ >= 0 && src.am_ == Offset) { |
| 1002 emit32(thumb32_mode8(LDRH_32_IMM2) | |
| 1003 thumb32_2reg_zero_extend_imm12(dst, src)); |
| 1004 return; |
| 1005 } else { |
| 1006 emit32(thumb32_mode8(LDRH_32_IMM3) | |
| 1007 thumb32_2reg_zero_extend_imm8(dst, src)); |
| 1008 return; |
| 1009 } |
| 1010 UNREACHABLE(); |
| 1011 } |
| 1012 |
| 1013 |
| 1014 void Assembler::ldrh_thumb_register(Register dst, const MemOperand& src) { |
| 1015 if (fits_thumb16_mode_4_1(dst, src)) { |
| 1016 // Encoding T1 (register) - 16 bit |
| 1017 emit16(thumb16_mode4_1(LDRH_REG) | thumb16_3lowreg_encoding(dst, src)); |
| 1018 return; |
| 1019 } else { |
| 1020 // Encoding T2 (register) - 32 bit |
| 1021 // Rn Rt imm2 Rm |
| 1022 emit32(thumb32_mode8(LDRH_32_REG) | thumb32_3reg_lsl(dst, src)); |
| 1023 return; |
| 1024 } |
| 1025 UNREACHABLE(); |
| 1026 } |
| 1027 |
| 1028 |
| 1029 void Assembler::ldrh_thumb(Register dst, const MemOperand& src) { |
| 1030 if (!src.rm_.is_valid()) { |
| 1031 // Immediate. |
| 1032 ldrh_thumb_immediate(dst, src) ; |
| 1033 return; |
| 1034 } else { |
| 1035 // Register. |
| 1036 ldrh_thumb_register(dst, src) ; |
| 1037 return; |
| 1038 } |
| 1039 UNREACHABLE(); |
| 1040 } |
| 1041 |
| 1042 |
| 1043 void Assembler::strh_thumb_immediate(Register src, const MemOperand& dst) { |
| 1044 if (fits_thumb16_mode_4(src, dst) && (dst.offset_ & 1) == 0) { |
| 1045 emit16(thumb16_mode4_4(STRH_IMM) | |
| 1046 thumb16_2lowreg_imm5_encoding(src, dst.rn_, (dst.offset_ >> 1))); |
| 1047 return; |
| 1048 } else if (dst.offset_ >= 0 && dst.am_ == Offset) { |
| 1049 emit32(thumb32_mode10(STRH_32_IMM2) | |
| 1050 thumb32_2reg_zero_extend_imm12(src, dst)); |
| 1051 return; |
| 1052 } else { |
| 1053 emit32(thumb32_mode10(STRH_32_IMM3) | |
| 1054 thumb32_2reg_zero_extend_imm8(src, dst)); |
| 1055 return; |
| 1056 } |
| 1057 UNREACHABLE(); |
| 1058 } |
| 1059 |
| 1060 |
| 1061 void Assembler::strh_thumb_register(Register src, const MemOperand& dst) { |
| 1062 if (fits_thumb16_mode_4_1(src, dst)) { |
| 1063 // Encoding T1 (register) - 16 bit |
| 1064 emit16(thumb16_mode4_1(STRH_REG) | thumb16_3lowreg_encoding(src, dst)); |
| 1065 return; |
| 1066 |
| 1067 } else { |
| 1068 // Encoding T2 (register) - 32 bit |
| 1069 // Rn Rt imm2 Rm |
| 1070 emit32(thumb32_mode10(STRH_32_REG) | thumb32_3reg_lsl(src, dst)); |
| 1071 return; |
| 1072 } |
| 1073 UNREACHABLE(); |
| 1074 } |
| 1075 |
| 1076 |
| 1077 void Assembler::strh_thumb(Register src, const MemOperand& dst) { |
| 1078 if (!dst.rm_.is_valid()) { |
| 1079 // Immediate. |
| 1080 strh_thumb_immediate(src, dst) ; |
| 1081 return; |
| 1082 } else { |
| 1083 // Register. |
| 1084 strh_thumb_register(src, dst) ; |
| 1085 return; |
| 1086 } |
| 1087 UNREACHABLE(); |
| 1088 } |
| 1089 |
| 1090 |
| 1091 void Assembler::ldrsb_thumb_immediate(Register dst, const MemOperand& src) { |
| 1092 if (src.offset_ >= 0 && src.am_ == Offset) { |
| 1093 // T1 - Rn Rt imm12 ZeroX, no neg offset |
| 1094 emit32(thumb32_mode9(LDRSB_32_IMM1) | |
| 1095 thumb32_2reg_zero_extend_imm12(dst, src)); |
| 1096 return; |
| 1097 } else { |
| 1098 // T2 - Rn Rt PUW imm8 |
| 1099 emit32(thumb32_mode9(LDRSB_32_IMM2) | |
| 1100 thumb32_2reg_zero_extend_imm8(dst, src)); |
| 1101 return; |
| 1102 } |
| 1103 UNREACHABLE(); |
| 1104 } |
| 1105 |
| 1106 |
| 1107 void Assembler::ldrsb_thumb_register(Register dst, const MemOperand& src) { |
| 1108 if (fits_thumb16_mode_4_1(dst, src)) { |
| 1109 // Encoding T1 (register) - 16 bit |
| 1110 emit16(thumb16_mode4_1(LDRSB_REG) | thumb16_3lowreg_encoding(dst, src)); |
| 1111 return; |
| 1112 } else { |
| 1113 // Encoding T2 (register) - 32 bit |
| 1114 emit32(thumb32_mode9(LDRSB_32_REG) | thumb32_3reg_lsl(dst, src)); |
| 1115 return; |
| 1116 } |
| 1117 UNREACHABLE(); |
| 1118 } |
| 1119 |
| 1120 |
| 1121 void Assembler::ldrsb_thumb(Register dst, const MemOperand& src) { |
| 1122 if (!src.rm_.is_valid()) { |
| 1123 // Immediate. |
| 1124 ldrsb_thumb_immediate(dst, src) ; |
| 1125 return; |
| 1126 } else { |
| 1127 // Register |
| 1128 ldrsb_thumb_register(dst, src) ; |
| 1129 return; |
| 1130 } |
| 1131 UNREACHABLE(); |
| 1132 } |
| 1133 |
| 1134 |
| 1135 void Assembler::ldrsh_thumb(Register dst, const MemOperand& src) { |
| 1136 if (!src.rm_.is_valid()) { |
| 1137 // Immediate. |
| 1138 ldrsh_thumb_immediate(dst, src) ; |
| 1139 return; |
| 1140 } else { |
| 1141 // Register. |
| 1142 ldrsh_thumb_register(dst, src) ; |
| 1143 return; |
| 1144 } |
| 1145 UNREACHABLE(); |
| 1146 } |
| 1147 |
| 1148 |
| 1149 void Assembler::ldrsh_thumb_immediate(Register dst, const MemOperand& src) { |
| 1150 // T1 & T2 both 32 bit |
| 1151 if (src.offset_ >= 0 && src.am_ == Offset) { |
| 1152 emit32(thumb32_mode8(LDRSH_32_IMM1) | |
| 1153 thumb32_2reg_zero_extend_imm12(dst, src)); |
| 1154 return; |
| 1155 } else { |
| 1156 emit32(thumb32_mode8(LDRSH_32_IMM2) | |
| 1157 thumb32_2reg_zero_extend_imm8(dst, src)); |
| 1158 return; |
| 1159 } |
| 1160 UNREACHABLE(); |
| 1161 } |
| 1162 |
| 1163 |
| 1164 void Assembler::ldrsh_thumb_register(Register dst, const MemOperand& src) { |
| 1165 if (fits_thumb16_mode_4_1(dst, src)) { |
| 1166 // Encoding T1 (register) - 16 bit |
| 1167 emit16(thumb16_mode4_1(LDRSH_REG) | thumb16_3lowreg_encoding(dst, src)); |
| 1168 return; |
| 1169 } else { |
| 1170 // Encoding T2 (register) - 32 bit |
| 1171 emit32(thumb32_mode8(LDRSH_32_REG) | thumb32_3reg_lsl(dst, src)); |
| 1172 return; |
| 1173 } |
| 1174 UNREACHABLE(); |
| 1175 } |
| 1176 |
| 1177 |
| 1178 void Assembler::mla_thumb(Register dst, Register src1, Register src2, |
| 1179 Register srcA, SBit s, Condition cond) { |
| 1180 ASSERT(cond == al && s == LeaveCC); |
| 1181 emit32(thumb32_mode16(MLA_32) | |
| 1182 thumb32_4reg(dst, src1, src2, srcA)); |
| 1183 } |
| 1184 |
| 1185 |
| 1186 void Assembler::mls_thumb(Register dst, Register src1, Register src2, |
| 1187 Register srcA, Condition cond) { |
| 1188 ASSERT(cond == al); |
| 1189 emit32(thumb32_mode16(MLS_32) | |
| 1190 thumb32_4reg(dst, src1, src2, srcA)); |
| 1191 } |
| 1192 |
| 1193 |
| 1194 void Assembler::sdiv_thumb(Register dst, Register src1, Register src2, |
| 1195 Condition cond) { |
| 1196 ASSERT(cond == al); |
| 1197 emit32(thumb32_mode17(SDIV_32) | thumb32_4reg(dst, src1, src2, pc) | |
| 1198 B7 | B6 | B5 | B4); |
| 1199 } |
| 1200 |
| 1201 |
| 1202 void Assembler::smlal_thumb(Register dstL, Register dstH, Register src1, |
| 1203 Register src2, SBit s, Condition cond) { |
| 1204 ASSERT(cond == al && s == LeaveCC); |
| 1205 ASSERT(dstL.code() != dstH.code()); |
| 1206 emit32(thumb32_mode17(SMLAL_32) | thumb32_4reg(dstH, src1, src2, dstL)); |
| 1207 } |
| 1208 |
| 1209 |
| 1210 void Assembler::smull_thumb(Register dstL, Register dstH, Register src1, |
| 1211 Register src2, SBit s, Condition cond) { |
| 1212 ASSERT(cond == al && s == LeaveCC); |
| 1213 ASSERT(dstL.code() != dstH.code()); |
| 1214 emit32(thumb32_mode17(SMULL_32) | thumb32_4reg(dstH, src1, src2, dstL)); |
| 1215 } |
| 1216 |
| 1217 |
| 1218 void Assembler::umlal_thumb(Register dstL, Register dstH, Register src1, |
| 1219 Register src2, SBit s, Condition cond) { |
| 1220 ASSERT(cond == al && s == LeaveCC); |
| 1221 ASSERT(dstL.code() != dstH.code()); |
| 1222 emit32(thumb32_mode17(UMLAL_32) | thumb32_4reg(dstH, src1, src2, dstL)); |
| 1223 } |
| 1224 |
| 1225 |
| 1226 void Assembler::umull_thumb(Register dstL, Register dstH, Register src1, |
| 1227 Register src2, SBit s, Condition cond) { |
| 1228 ASSERT(cond == al && s == LeaveCC); |
| 1229 ASSERT(dstL.code() != dstH.code()); |
| 1230 emit32(thumb32_mode17(UMULL_32) | thumb32_4reg(dstH, src1, src2, dstL)); |
| 1231 } |
| 1232 |
| 1233 |
| 1234 void Assembler::ldm_thumb(BlockAddrMode am, |
| 1235 Register base, |
| 1236 RegList dst, |
| 1237 Condition cond) { |
| 1238 ASSERT(cond == al); |
| 1239 ASSERT((((am & P) >> 24) & 1) != (((am & U) >> 23) & 1)); |
| 1240 if (is_uint3(base.code()) && is_uint8(dst)) { |
| 1241 if ((((am & W) >> 21) & 1) ^ ((dst >> base.code()) & 1)) { |
| 1242 emit16(B15 | B14 | B11 | base.code()*B8 | (dst & 0xff)); |
| 1243 return; |
| 1244 } |
| 1245 } |
| 1246 ASSERT((dst & sp.bit()) == 0); |
| 1247 emit32(thumb32_mode5() | am | L | base.code()*BH0 | dst); |
| 1248 } |
| 1249 |
| 1250 |
| 1251 void Assembler::stm_thumb(BlockAddrMode am, |
| 1252 Register base, |
| 1253 RegList dst, |
| 1254 Condition cond) { |
| 1255 ASSERT(dst != 0); |
| 1256 ASSERT(cond == al); |
| 1257 ASSERT((((am & P) >> 24) & 1) != (((am & U) >> 23) & 1)); |
| 1258 if (is_uint3(base.code()) && is_uint8(dst) && am == ia_w) { |
| 1259 emit16(B15 | B14 | base.code()*B8 | dst); |
| 1260 return; |
| 1261 } |
| 1262 ASSERT((dst & sp.bit()) == 0 && (dst & pc.bit()) == 0); |
| 1263 emit32(thumb32_mode5() | am | base.code()*BH0 | dst); |
| 1264 } |
| 1265 |
| 1266 |
| 1267 void Assembler::movt_thumb(Register reg, uint32_t immediate, Condition cond) { |
| 1268 emit32(thumb32_mode3(MOVT_32_IMM) | |
| 1269 thumb32_1reg_zero_extend_imm_split_4i38(reg, immediate)); |
| 1270 } |
| 1271 |
| 1272 |
| 1273 void Assembler::ldr_pc_thumb(Register dst, const Operand& src) { |
| 1274 RecordRelocInfo(src.rmode_, src.imm32_, USE_CONSTANT_POOL); |
| 1275 ldr_thumb(dst, MemOperand(pc, 0)); |
| 1276 } |
| 1277 |
711 } } // namespace v8::internal | 1278 } } // namespace v8::internal |
712 | 1279 |
713 #endif // V8_TARGET_ARCH_ARM | 1280 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |