Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(873)

Side by Side Diff: runtime/vm/intrinsifier_x64.cc

Issue 648613006: Implement bigint absAdd, absSub, mulAdd, sqrAdd, estQuotientDigit intrinsics, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 void Intrinsifier::Bigint_setDigits(Assembler* assembler) { 816 void Intrinsifier::Bigint_setDigits(Assembler* assembler) {
817 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 817 __ movq(RAX, Address(RSP, + 1 * kWordSize));
818 __ movq(RCX, Address(RSP, + 2 * kWordSize)); 818 __ movq(RCX, Address(RSP, + 2 * kWordSize));
819 __ StoreIntoObject(RCX, 819 __ StoreIntoObject(RCX,
820 FieldAddress(RCX, Bigint::digits_offset()), RAX, false); 820 FieldAddress(RCX, Bigint::digits_offset()), RAX, false);
821 __ ret(); 821 __ ret();
822 } 822 }
823 823
824 824
825 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { 825 void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
826 // TODO(regis): Implement. 826 // static void _absAdd(Uint32List digits, int used,
827 // Uint32List a_digits, int a_used,
828 // Uint32List r_digits)
829
830 __ movq(RDI, Address(RSP, 5 * kWordSize)); // digits
831 __ movq(R8, Address(RSP, 4 * kWordSize)); // used is Smi
832 __ SmiUntag(R8); // used > 0.
833 __ movq(RSI, Address(RSP, 3 * kWordSize)); // a_digits
834 __ movq(RCX, Address(RSP, 2 * kWordSize)); // a_used is Smi
835 __ SmiUntag(RCX); // a_used > 0.
836 __ movq(RBX, Address(RSP, 1 * kWordSize)); // r_digits
837
838 // Precompute 'used - a_used' now so that carry flag is not lost later.
839 __ subq(R8, RCX);
840 __ incq(R8); // To account for the extra test between loops.
841
842 __ xorq(RDX, RDX); // RDX = 0, carry flag = 0.
843 Label add_loop;
844 __ Bind(&add_loop);
845 __ movl(RAX, FieldAddress(RDI, RDX, TIMES_4, TypedData::data_offset()));
846 __ adcl(RAX, FieldAddress(RSI, RDX, TIMES_4, TypedData::data_offset()));
847 __ movl(FieldAddress(RBX, RDX, TIMES_4, TypedData::data_offset()), RAX);
848 __ incq(RDX); // Does not affect carry flag.
849 __ decq(RCX); // Does not affect carry flag.
zra 2014/10/10 16:23:43 Is this supposed to be R8? If not, RCX appears unu
regis 2014/10/10 19:15:47 RCX is the counter for the first loop, R8 for the
zra 2014/10/10 19:34:56 Oh, sorry. I was confused by our conversation the
850 __ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
851
852 Label last_carry;
853 __ decq(R8); // Does not affect carry flag.
854 __ j(ZERO, &last_carry, Assembler::kNearJump);
855
856 Label carry_loop;
857 __ Bind(&carry_loop);
858 __ movl(RAX, FieldAddress(RDI, RDX, TIMES_4, TypedData::data_offset()));
859 __ adcl(RAX, Immediate(0));
860 __ movl(FieldAddress(RBX, RDX, TIMES_4, TypedData::data_offset()), RAX);
861 __ incq(RDX); // Does not affect carry flag.
862 __ decq(R8); // Does not affect carry flag.
863 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
864
865 __ Bind(&last_carry);
866 __ movl(RAX, Immediate(0));
867 __ adcl(RAX, Immediate(0));
868 __ movl(FieldAddress(RBX, RDX, TIMES_4, TypedData::data_offset()), RAX);
869
870 // Returning Object::null() is not required, since this method is private.
871 __ ret();
827 } 872 }
828 873
829 874
830 void Intrinsifier::Bigint_absSub(Assembler* assembler) { 875 void Intrinsifier::Bigint_absSub(Assembler* assembler) {
831 // TODO(regis): Implement. 876 // static void _absSub(Uint32List digits, int used,
877 // Uint32List a_digits, int a_used,
878 // Uint32List r_digits)
879
880 __ movq(RDI, Address(RSP, 5 * kWordSize)); // digits
881 __ movq(R8, Address(RSP, 4 * kWordSize)); // used is Smi
882 __ SmiUntag(R8); // used > 0.
883 __ movq(RSI, Address(RSP, 3 * kWordSize)); // a_digits
884 __ movq(RCX, Address(RSP, 2 * kWordSize)); // a_used is Smi
885 __ SmiUntag(RCX); // a_used > 0.
886 __ movq(RBX, Address(RSP, 1 * kWordSize)); // r_digits
887
888 // Precompute 'used - a_used' now so that carry flag is not lost later.
889 __ subq(R8, RCX);
890 __ incq(R8); // To account for the extra test between loops.
891
892 __ xorq(RDX, RDX); // RDX = 0, carry flag = 0.
893 Label sub_loop;
894 __ Bind(&sub_loop);
895 __ movl(RAX, FieldAddress(RDI, RDX, TIMES_4, TypedData::data_offset()));
896 __ sbbl(RAX, FieldAddress(RSI, RDX, TIMES_4, TypedData::data_offset()));
897 __ movl(FieldAddress(RBX, RDX, TIMES_4, TypedData::data_offset()), RAX);
898 __ incq(RDX); // Does not affect carry flag.
899 __ decq(RCX); // Does not affect carry flag.
zra 2014/10/10 16:23:43 Same question.
regis 2014/10/10 19:15:47 ditto
900 __ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
901
902 Label done;
903 __ decq(R8); // Does not affect carry flag.
904 __ j(ZERO, &done, Assembler::kNearJump);
905
906 Label carry_loop;
907 __ Bind(&carry_loop);
908 __ movl(RAX, FieldAddress(RDI, RDX, TIMES_4, TypedData::data_offset()));
909 __ sbbl(RAX, Immediate(0));
910 __ movl(FieldAddress(RBX, RDX, TIMES_4, TypedData::data_offset()), RAX);
911 __ incq(RDX); // Does not affect carry flag.
912 __ decq(R8); // Does not affect carry flag.
913 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
914
915 __ Bind(&done);
916 // Returning Object::null() is not required, since this method is private.
917 __ ret();
832 } 918 }
833 919
834 920
835 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { 921 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
836 // TODO(regis): Implement. 922 // Pseudo code:
923 // static void _mulAdd(Uint32List x_digits, int xi,
924 // Uint32List m_digits, int i,
925 // Uint32List a_digits, int j, int n) {
926 // uint32_t x = x_digits[xi >> 1]; // xi is Smi.
927 // if (x == 0 || n == 0) {
928 // return;
929 // }
930 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi.
931 // uint32_t* ajp = &a_digits[j >> 1]; // j is Smi.
932 // uint32_t c = 0;
933 // SmiUntag(n);
934 // do {
935 // uint32_t mi = *mip++;
936 // uint32_t aj = *ajp;
937 // uint64_t t = x*mi + aj + c; // 32-bit * 32-bit -> 64-bit.
938 // *ajp++ = low32(t);
939 // c = high32(t);
940 // } while (--n > 0);
941 // while (c != 0) {
942 // uint64_t t = *ajp + c;
943 // *ajp++ = low32(t);
944 // c = high32(t); // c == 0 or 1.
945 // }
946 // }
947
948 Label done;
949 // RBX = x, done if x == 0
950 __ movq(RCX, Address(RSP, 7 * kWordSize)); // x_digits
951 __ movq(RAX, Address(RSP, 6 * kWordSize)); // xi is Smi
952 __ movl(RBX, FieldAddress(RCX, RAX, TIMES_2, TypedData::data_offset()));
953 __ testl(RBX, RBX);
954 __ j(ZERO, &done, Assembler::kNearJump);
955
956 // R8 = SmiUntag(n), no_op if n == 0
957 __ movq(R8, Address(RSP, 1 * kWordSize));
958 __ SmiUntag(R8);
959 __ j(ZERO, &done, Assembler::kNearJump);
960
961 // RDI = mip = &m_digits[i >> 1]
962 __ movq(RDI, Address(RSP, 5 * kWordSize)); // m_digits
963 __ movq(RAX, Address(RSP, 4 * kWordSize)); // i is Smi
964 __ leaq(RDI, FieldAddress(RDI, RAX, TIMES_2, TypedData::data_offset()));
965
966 // RSI = ajp = &a_digits[j >> 1]
967 __ movq(RSI, Address(RSP, 3 * kWordSize)); // a_digits
968 __ movq(RAX, Address(RSP, 2 * kWordSize)); // j is Smi
969 __ leaq(RSI, FieldAddress(RSI, RAX, TIMES_2, TypedData::data_offset()));
970
971 // RCX = c = 0
972 __ xorq(RCX, RCX);
973
974 Label muladd_loop;
975 __ Bind(&muladd_loop);
976 // x: RBX
977 // mip: RDI
978 // ajp: RSI
979 // c: RCX
980 // t: RDX:RAX (not live at loop entry)
981 // n: R8
982
983 // uint32_t mi = *mip++
984 __ movl(RAX, Address(RDI, 0));
985 __ addq(RDI, Immediate(Bigint::kBytesPerDigit));
986
987 // uint64_t t = x*mi
988 __ mull(RBX); // t = RDX:RAX = RAX * RBX, 32-bit * 32-bit -> 64-bit
989 __ addl(RAX, RCX); // t += c
990 __ adcl(RDX, Immediate(0));
991
992 // uint32_t aj = *ajp; t += aj
993 __ addl(RAX, Address(RSI, 0));
994 __ adcl(RDX, Immediate(0));
995
996 // *ajp++ = low32(t)
997 __ movl(Address(RSI, 0), RAX);
998 __ addq(RSI, Immediate(Bigint::kBytesPerDigit));
999
1000 // c = high32(t)
1001 __ movl(RCX, RDX);
1002
1003 // while (--n > 0)
1004 __ decq(R8); // --n
1005 __ j(NOT_ZERO, &muladd_loop, Assembler::kNearJump);
1006
1007 __ testl(RCX, RCX);
1008 __ j(ZERO, &done, Assembler::kNearJump);
1009
1010 // *ajp += c
1011 __ addl(Address(RSI, 0), RCX);
1012 __ j(NOT_CARRY, &done, Assembler::kNearJump);
1013
1014 Label propagate_carry_loop;
1015 __ Bind(&propagate_carry_loop);
1016 __ addq(RSI, Immediate(Bigint::kBytesPerDigit));
1017 __ incl(Address(RSI, 0)); // c == 0 or 1
1018 __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump);
1019
1020 __ Bind(&done);
1021 // Returning Object::null() is not required, since this method is private.
1022 __ ret();
837 } 1023 }
838 1024
839 1025
840 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { 1026 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
841 // TODO(regis): Implement. 1027 // Pseudo code:
1028 // static void _sqrAdd(Uint32List x_digits, int i,
1029 // Uint32List a_digits, int used) {
1030 // uint32_t* xip = &x_digits[i >> 1]; // i is Smi.
1031 // uint32_t x = *xip++;
1032 // if (x == 0) return;
1033 // uint32_t* ajp = &a_digits[i]; // j == 2*i, i is Smi.
1034 // uint32_t aj = *ajp;
1035 // uint64_t t = x*x + aj;
1036 // *ajp++ = low32(t);
1037 // uint64_t c = high32(t);
1038 // int n = ((used - i) >> 1) - 1; // used and i are Smi.
1039 // while (--n >= 0) {
1040 // uint32_t xi = *xip++;
1041 // uint32_t aj = *ajp;
1042 // uint96_t t = 2*x*xi + aj + c; // 2-bit * 32-bit * 32-bit -> 65-bit.
1043 // *ajp++ = low32(t);
1044 // c = high64(t); // 33-bit.
1045 // }
1046 // uint32_t aj = *ajp;
1047 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit.
1048 // *ajp++ = low32(t);
1049 // *ajp = high32(t);
1050 // }
1051
1052 // RDI = xip = &x_digits[i >> 1]
1053 __ movq(RDI, Address(RSP, 4 * kWordSize)); // x_digits
1054 __ movq(RAX, Address(RSP, 3 * kWordSize)); // i is Smi
1055 __ leaq(RDI, FieldAddress(RDI, RAX, TIMES_2, TypedData::data_offset()));
1056
1057 // RBX = x = *xip++, return if x == 0
1058 Label x_zero;
1059 __ movl(RBX, Address(RDI, 0));
1060 __ cmpl(RBX, Immediate(0));
1061 __ j(EQUAL, &x_zero, Assembler::kNearJump);
1062 __ addq(RDI, Immediate(Bigint::kBytesPerDigit));
1063
1064 // RSI = ajp = &a_digits[i]
1065 __ movq(RSI, Address(RSP, 2 * kWordSize)); // a_digits
1066 __ leaq(RSI, FieldAddress(RSI, RAX, TIMES_4, TypedData::data_offset()));
1067
1068 // RDX:RAX = t = x*x + *ajp
1069 __ movl(RAX, RBX);
1070 __ mull(RBX);
1071 __ addl(RAX, Address(RSI, 0));
1072 __ adcl(RDX, Immediate(0));
1073
1074 // *ajp++ = low32(t)
1075 __ movl(Address(RSI, 0), RAX);
1076 __ addq(RSI, Immediate(Bigint::kBytesPerDigit));
1077
1078 // int n = used - i - 1
1079 __ movq(R8, Address(RSP, 1 * kWordSize)); // used is Smi
1080 __ subq(R8, Address(RSP, 3 * kWordSize)); // i is Smi
1081 __ SmiUntag(R8);
1082 __ decq(R8);
1083
1084 // uint64_t c = high32(t)
1085 __ xorl(R13, R13); // R13 = high32(c) == 0
1086 __ movl(R12, RDX); // R12 = low32(c) == high32(t)
1087
1088 Label loop, done;
1089 __ Bind(&loop);
1090 // x: RBX
1091 // xip: RDI
1092 // ajp: RSI
1093 // c: R13:R12
1094 // t: RCX:RDX:RAX (not live at loop entry)
1095 // n: R8
1096
1097 // while (--n >= 0)
1098 __ decq(R8); // --n
1099 __ j(NEGATIVE, &done, Assembler::kNearJump);
1100
1101 // uint32_t xi = *xip++
1102 __ movl(RAX, Address(RDI, 0));
1103 __ addq(RDI, Immediate(Bigint::kBytesPerDigit));
1104
1105 // uint96_t t = RCX:RDX:RAX = 2*x*xi + aj + c
1106 __ mull(RBX); // RDX:RAX = RAX * RBX
1107 __ xorl(RCX, RCX); // RCX = 0
1108 __ shldl(RCX, RDX, Immediate(1));
1109 __ shldl(RDX, RAX, Immediate(1));
1110 __ shll(RAX, Immediate(1)); // RCX:RDX:RAX <<= 1
1111 __ addl(RAX, Address(RSI, 0)); // t += aj
1112 __ adcl(RDX, Immediate(0));
1113 __ adcl(RCX, Immediate(0));
1114 __ addl(RAX, R12); // t += low32(c)
1115 __ adcl(RDX, R13); // t += high32(c) << 32
1116 __ adcl(RCX, Immediate(0));
1117
1118 // *ajp++ = low32(t)
1119 __ movl(Address(RSI, 0), RAX);
1120 __ addq(RSI, Immediate(Bigint::kBytesPerDigit));
1121
1122 // c = high64(t)
1123 __ movl(R12, RDX);
1124 __ movl(R13, RCX);
1125
1126 __ jmp(&loop, Assembler::kNearJump);
1127
1128 __ Bind(&done);
1129 // uint64_t t = aj + c
1130 __ addl(R12, Address(RSI, 0)); // t = c, t += *ajp
1131 __ adcl(R13, Immediate(0));
1132
1133 // *ajp++ = low32(t)
1134 // *ajp = high32(t)
1135 __ movl(Address(RSI, 0), R12);
1136 __ movl(Address(RSI, Bigint::kBytesPerDigit), R13);
1137
1138 __ Bind(&x_zero);
1139 // Returning Object::null() is not required, since this method is private.
1140 __ ret();
842 } 1141 }
843 1142
844 1143
845 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { 1144 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
846 // TODO(regis): Implement. 1145 // Pseudo code:
1146 // static void _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
1147 // uint32_t yt = args[_YT]; // _YT == 0.
1148 // uint32_t* dp = &digits[i >> 1]; // i is Smi.
1149 // uint32_t dh = dp[0]; // dh == digits[i >> 1].
1150 // uint32_t qd;
1151 // if (dh == yt) {
1152 // qd = DIGIT_MASK;
1153 // } else {
1154 // dl = dp[-1]; // dl == digits[(i - 1) >> 1].
1155 // qd = dh:dl / yt; // No overflow possible, because dh < yt.
1156 // }
1157 // args[_QD] = qd; // _QD == 1;
1158 // }
1159
1160 // RDI = args
1161 __ movq(RDI, Address(RSP, 3 * kWordSize)); // args
1162
1163 // RCX = yt = args[0]
1164 __ movl(RCX, FieldAddress(RDI, TypedData::data_offset()));
1165
1166 // RBX = dp = &digits[i >> 1]
1167 __ movq(RBX, Address(RSP, 2 * kWordSize)); // digits
1168 __ movq(RAX, Address(RSP, 1 * kWordSize)); // i is Smi
1169 __ leaq(RBX, FieldAddress(RBX, RAX, TIMES_2, TypedData::data_offset()));
1170
1171 // RDX = dh = dp[0]
1172 __ movl(RDX, Address(RBX, 0));
1173
1174 // RAX = qd = DIGIT_MASK = -1
1175 __ movl(RAX, Immediate(-1));
1176
1177 // Return qd if dh == yt
1178 Label return_qd;
1179 __ cmpl(RDX, RCX);
1180 __ j(EQUAL, &return_qd, Assembler::kNearJump);
1181
1182 // RAX = dl = dp[-1]
1183 __ movl(RAX, Address(RBX, -Bigint::kBytesPerDigit));
1184
1185 // RAX = qd = dh:dl / yt = RDX:RAX / RCX
1186 __ divl(RCX);
1187
1188 __ Bind(&return_qd);
1189 // args[1] = qd
1190 __ movl(FieldAddress(RDI, TypedData::data_offset() + Bigint::kBytesPerDigit),
1191 RAX);
1192
1193 // Returning Object::null() is not required, since this method is private.
1194 __ ret();
847 } 1195 }
848 1196
849 1197
850 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) { 1198 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
851 // TODO(regis): Implement. 1199 // Pseudo code:
852 } 1200 // static void _mulMod(Uint32List args, Uint32List digits, int i) {
853 1201 // uint32_t rho = args[_RHO]; // _RHO == 0.
854 1202 // uint32_t d = digits[i >> 1]; // i is Smi.
1203 // uint64_t t = rho*d;
1204 // args[_MU] = t mod DIGIT_BASE; // _MU == 1.
1205 // }
1206
1207 // RDI = args
1208 __ movq(RDI, Address(RSP, 3 * kWordSize)); // args
1209
1210 // RCX = rho = args[0]
1211 __ movl(RCX, FieldAddress(RDI, TypedData::data_offset()));
1212
1213 // RAX = digits[i >> 1]
1214 __ movq(RBX, Address(RSP, 2 * kWordSize)); // digits
1215 __ movq(RAX, Address(RSP, 1 * kWordSize)); // i is Smi
1216 __ movl(RAX, FieldAddress(RBX, RAX, TIMES_2, TypedData::data_offset()));
1217
1218 // RDX:RAX = t = rho*d
1219 __ mull(RCX);
1220
1221 // args[1] = t mod DIGIT_BASE = low32(t)
1222 __ movl(FieldAddress(RDI, TypedData::data_offset() + Bigint::kBytesPerDigit),
1223 RAX);
1224
1225 // Returning Object::null() is not required, since this method is private.
1226 __ ret();
1227 }
1228
1229
855 // Check if the last argument is a double, jump to label 'is_smi' if smi 1230 // Check if the last argument is a double, jump to label 'is_smi' if smi
856 // (easy to convert to double), otherwise jump to label 'not_double_smi', 1231 // (easy to convert to double), otherwise jump to label 'not_double_smi',
857 // Returns the last argument in RAX. 1232 // Returns the last argument in RAX.
858 static void TestLastArgumentIsDouble(Assembler* assembler, 1233 static void TestLastArgumentIsDouble(Assembler* assembler,
859 Label* is_smi, 1234 Label* is_smi,
860 Label* not_double_smi) { 1235 Label* not_double_smi) {
861 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 1236 __ movq(RAX, Address(RSP, + 1 * kWordSize));
862 __ testq(RAX, Immediate(kSmiTagMask)); 1237 __ testq(RAX, Immediate(kSmiTagMask));
863 __ j(ZERO, is_smi, Assembler::kNearJump); // Jump if Smi. 1238 __ j(ZERO, is_smi, Assembler::kNearJump); // Jump if Smi.
864 __ CompareClassId(RAX, kDoubleCid); 1239 __ CompareClassId(RAX, kDoubleCid);
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 __ incq(RAX); 1687 __ incq(RAX);
1313 __ Bind(&set_hash_code); 1688 __ Bind(&set_hash_code);
1314 __ SmiTag(RAX); 1689 __ SmiTag(RAX);
1315 __ movq(FieldAddress(RBX, String::hash_offset()), RAX); 1690 __ movq(FieldAddress(RBX, String::hash_offset()), RAX);
1316 __ ret(); 1691 __ ret();
1317 } 1692 }
1318 1693
1319 1694
1320 // Allocates one-byte string of length 'end - start'. The content is not 1695 // Allocates one-byte string of length 'end - start'. The content is not
1321 // initialized. 'length-reg' contains tagged length. 1696 // initialized. 'length-reg' contains tagged length.
1322 // Returns new string as tagged pointer in EAX. 1697 // Returns new string as tagged pointer in RAX.
1323 static void TryAllocateOnebyteString(Assembler* assembler, 1698 static void TryAllocateOnebyteString(Assembler* assembler,
1324 Label* ok, 1699 Label* ok,
1325 Label* failure, 1700 Label* failure,
1326 Register length_reg) { 1701 Register length_reg) {
1327 if (length_reg != RDI) { 1702 if (length_reg != RDI) {
1328 __ movq(RDI, length_reg); 1703 __ movq(RDI, length_reg);
1329 } 1704 }
1330 Label pop_and_fail; 1705 Label pop_and_fail;
1331 __ pushq(RDI); // Preserve length. 1706 __ pushq(RDI); // Preserve length.
1332 __ SmiUntag(RDI); 1707 __ SmiUntag(RDI);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 __ SmiUntag(RCX); 1827 __ SmiUntag(RCX);
1453 __ movb(FieldAddress(RAX, RBX, TIMES_1, OneByteString::data_offset()), RCX); 1828 __ movb(FieldAddress(RAX, RBX, TIMES_1, OneByteString::data_offset()), RCX);
1454 __ ret(); 1829 __ ret();
1455 } 1830 }
1456 1831
1457 1832
1458 void Intrinsifier::OneByteString_allocate(Assembler* assembler) { 1833 void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
1459 __ movq(RDI, Address(RSP, + 1 * kWordSize)); // Length.v= 1834 __ movq(RDI, Address(RSP, + 1 * kWordSize)); // Length.v=
1460 Label fall_through, ok; 1835 Label fall_through, ok;
1461 TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI); 1836 TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
1462 // EDI: Start address to copy from (untagged). 1837 // RDI: Start address to copy from (untagged).
1463 1838
1464 __ Bind(&ok); 1839 __ Bind(&ok);
1465 __ ret(); 1840 __ ret();
1466 1841
1467 __ Bind(&fall_through); 1842 __ Bind(&fall_through);
1468 } 1843 }
1469 1844
1470 1845
1471 // TODO(srdjan): Add combinations (one-byte/two-byte/external strings). 1846 // TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
1472 void StringEquality(Assembler* assembler, intptr_t string_cid) { 1847 void StringEquality(Assembler* assembler, intptr_t string_cid) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 // Set return value to Isolate::current_tag_. 1953 // Set return value to Isolate::current_tag_.
1579 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); 1954 __ movq(RAX, Address(RBX, Isolate::current_tag_offset()));
1580 __ ret(); 1955 __ ret();
1581 } 1956 }
1582 1957
1583 #undef __ 1958 #undef __
1584 1959
1585 } // namespace dart 1960 } // namespace dart
1586 1961
1587 #endif // defined TARGET_ARCH_X64 1962 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698