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

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

Powered by Google App Engine
This is Rietveld 408576698