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

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 10382033: x86/x64 port of Math.floor(x/y) to use integer division for specific divisor (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 7 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 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 945 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 // Sign extend to edx. 956 // Sign extend to edx.
957 __ cdq(); 957 __ cdq();
958 __ idiv(right_reg); 958 __ idiv(right_reg);
959 959
960 // Deoptimize if remainder is not 0. 960 // Deoptimize if remainder is not 0.
961 __ test(edx, Operand(edx)); 961 __ test(edx, Operand(edx));
962 DeoptimizeIf(not_zero, instr->environment()); 962 DeoptimizeIf(not_zero, instr->environment());
963 } 963 }
964 964
965 965
966 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
967 ASSERT(instr->InputAt(1)->IsConstantOperand());
968
969 Register dividend = ToRegister(instr->InputAt(0));
970 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
971 Register result = ToRegister(instr->result());
972
973 switch (divisor) {
974 case 0:
975 DeoptimizeIf(no_condition, instr->environment());
976 return;
977
978 case 1:
979 __ Move(result, dividend);
980 return;
981
982 case -1:
983 __ Move(result, dividend);
984 __ neg(result);
985 // FIXME: set & check HValue::kBailoutOnMinusZero
Yang 2012/06/19 15:41:38 Is this going to be fixed?
986 DeoptimizeIf(zero, instr->environment());
987 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
988 DeoptimizeIf(overflow, instr->environment());
989 }
990 return;
991 }
992
993 uint32_t divisor_abs = abs(divisor);
994 if (IsPowerOf2(divisor_abs)) {
995 int32_t power = WhichPowerOf2(divisor_abs);
996 if (divisor < 0) {
997 // input[dividend] is clobbered
998 // tedious because neg(dividend) might overflow
Yang 2012/06/19 15:41:38 Comments should start with capital letter and end
999 __ mov(result, dividend);
1000 __ sar(dividend, 31);
1001 __ neg(result);
1002 // FIXME: set & check HValue::kBailoutOnMinusZero
1003 DeoptimizeIf(zero, instr->environment());
1004 __ shl(dividend, 32 - power);
1005 __ sar(result, power);
1006 __ not_(dividend);
1007 // clear result.sign if dividend.sign
1008 __ and_(result, dividend);
1009 } else {
1010 __ Move(result, dividend);
1011 __ sar(result, power);
1012 }
1013 } else {
1014 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
1015 ASSERT(ToRegister(instr->result()).is(edx));
1016 Register scratch = ToRegister(instr->TempAt(0));
1017
1018 // b: 2^b < divisor_abs < 2^(b+1)
1019 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
1020 unsigned shift = 32 + b; // precision +1bit (effectively)
1021 double multiplier_f = static_cast<double>((uint64_t)1 << shift)
Yang 2012/06/19 15:41:38 Use static_cast please.
1022 / divisor_abs;
1023 int64_t multiplier;
1024 if (multiplier_f - floor(multiplier_f) < 0.5) {
1025 multiplier = floor(multiplier_f);
1026 } else {
1027 multiplier = floor(multiplier_f) + 1;
1028 }
1029 // multiplier is a uint32
1030 ASSERT(multiplier > 0 && multiplier < ((int64_t)1<<32));
Yang 2012/06/19 15:41:38 Use static_cast please.
1031 __ mov(scratch, dividend);
1032 // FIXME: set & check HValue::kBailoutOnMinusZero
Yang 2012/06/19 15:41:38 Same here.
1033 if (divisor < 0) {
1034 __ test(dividend, dividend);
1035 DeoptimizeIf(zero, instr->environment());
1036 }
1037 __ mov(edx, multiplier);
1038 __ imul(edx);
1039 if ((int32_t)multiplier < 0) {
Yang 2012/06/19 15:41:38 Use static_cast please.
1040 __ add(edx, scratch);
1041 }
1042 Register reg_lo = eax;
1043 Register reg_byte_scratch = scratch;
1044 if (!reg_byte_scratch.is_byte_register()) {
1045 __ xchg(reg_lo, reg_byte_scratch);
1046 reg_lo = scratch;
1047 reg_byte_scratch = eax;
1048 }
1049 if (divisor < 0) {
1050 __ xor_(reg_byte_scratch, reg_byte_scratch);
1051 __ cmp(reg_lo, 0x40000000);
1052 __ setcc(above, reg_byte_scratch);
1053 __ neg(edx);
1054 __ sub(edx, reg_byte_scratch);
1055 } else {
1056 __ xor_(reg_byte_scratch, reg_byte_scratch);
1057 __ cmp(reg_lo, 0xC0000000);
1058 __ setcc(above_equal, reg_byte_scratch);
1059 __ add(edx, reg_byte_scratch);
1060 }
1061 __ sar(edx, shift - 32);
1062 }
1063 }
1064
1065
966 void LCodeGen::DoMulI(LMulI* instr) { 1066 void LCodeGen::DoMulI(LMulI* instr) {
967 Register left = ToRegister(instr->InputAt(0)); 1067 Register left = ToRegister(instr->InputAt(0));
968 LOperand* right = instr->InputAt(1); 1068 LOperand* right = instr->InputAt(1);
969 1069
970 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1070 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
971 __ mov(ToRegister(instr->TempAt(0)), left); 1071 __ mov(ToRegister(instr->TempAt(0)), left);
972 } 1072 }
973 1073
974 if (right->IsConstantOperand()) { 1074 if (right->IsConstantOperand()) {
975 // Try strength reductions on the multiplication. 1075 // Try strength reductions on the multiplication.
(...skipping 4081 matching lines...) Expand 10 before | Expand all | Expand 10 after
5057 FixedArray::kHeaderSize - kPointerSize)); 5157 FixedArray::kHeaderSize - kPointerSize));
5058 __ bind(&done); 5158 __ bind(&done);
5059 } 5159 }
5060 5160
5061 5161
5062 #undef __ 5162 #undef __
5063 5163
5064 } } // namespace v8::internal 5164 } } // namespace v8::internal
5065 5165
5066 #endif // V8_TARGET_ARCH_IA32 5166 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/disasm-ia32.cc ('k') | src/ia32/lithium-ia32.h » ('j') | src/x64/lithium-codegen-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698