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

Side by Side Diff: src/mips64/assembler-mips64.cc

Issue 2505923002: MIPS64: Port "Reland of "MIPS: Optimize load/store with large offset"". (Closed)
Patch Set: Remove unnecessary check for Float64 instructions Created 4 years 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
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 emit(instr); 1933 emit(instr);
1934 } 1934 }
1935 1935
1936 1936
1937 // ------------Memory-instructions------------- 1937 // ------------Memory-instructions-------------
1938 1938
1939 // Helper for base-reg + offset, when offset is larger than int16. 1939 // Helper for base-reg + offset, when offset is larger than int16.
1940 void Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) { 1940 void Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) {
1941 DCHECK(!src.rm().is(at)); 1941 DCHECK(!src.rm().is(at));
1942 DCHECK(is_int32(src.offset_)); 1942 DCHECK(is_int32(src.offset_));
1943 daddiu(at, zero_reg, (src.offset_ >> kLuiShift) & kImm16Mask); 1943 lui(at, (src.offset_ >> kLuiShift) & kImm16Mask);
1944 dsll(at, at, kLuiShift);
1945 ori(at, at, src.offset_ & kImm16Mask); // Load 32-bit offset. 1944 ori(at, at, src.offset_ & kImm16Mask); // Load 32-bit offset.
1946 daddu(at, at, src.rm()); // Add base register. 1945 daddu(at, at, src.rm()); // Add base register.
1947 } 1946 }
1948 1947
1948 // Helper for base-reg + upper part of offset, when offset is larger than int16.
1949 // Loads higher part of the offset to AT register.
1950 // Returns lower part of the offset to be used as offset
1951 // in Load/Store instructions
1952 int32_t Assembler::LoadRegPlusUpperOffsetPartToAt(const MemOperand& src) {
1953 DCHECK(!src.rm().is(at));
1954 DCHECK(is_int32(src.offset_));
1955 int32_t hi = (src.offset_ >> kLuiShift) & kImm16Mask;
1956 // If the highest bit of the lower part of the offset is 1, this would make
1957 // the offset in the load/store instruction negative. We need to compensate
1958 // for this by adding 1 to the upper part of the offset.
1959 if (src.offset_ & kNegOffset) {
1960 if ((hi & kNegOffset) != ((hi + 1) & kNegOffset)) {
1961 LoadRegPlusOffsetToAt(src);
1962 return 0;
1963 }
1964
1965 hi += 1;
1966 }
1967
1968 lui(at, hi);
1969 daddu(at, at, src.rm());
1970 return (src.offset_ & kImm16Mask);
1971 }
1949 1972
1950 void Assembler::lb(Register rd, const MemOperand& rs) { 1973 void Assembler::lb(Register rd, const MemOperand& rs) {
1951 if (is_int16(rs.offset_)) { 1974 if (is_int16(rs.offset_)) {
1952 GenInstrImmediate(LB, rs.rm(), rd, rs.offset_); 1975 GenInstrImmediate(LB, rs.rm(), rd, rs.offset_);
1953 } else { // Offset > 16 bits, use multiple instructions to load. 1976 } else { // Offset > 16 bits, use multiple instructions to load.
1954 LoadRegPlusOffsetToAt(rs); 1977 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
1955 GenInstrImmediate(LB, at, rd, 0); // Equiv to lb(rd, MemOperand(at, 0)); 1978 GenInstrImmediate(LB, at, rd, off16);
1956 } 1979 }
1957 } 1980 }
1958 1981
1959 1982
1960 void Assembler::lbu(Register rd, const MemOperand& rs) { 1983 void Assembler::lbu(Register rd, const MemOperand& rs) {
1961 if (is_int16(rs.offset_)) { 1984 if (is_int16(rs.offset_)) {
1962 GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_); 1985 GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_);
1963 } else { // Offset > 16 bits, use multiple instructions to load. 1986 } else { // Offset > 16 bits, use multiple instructions to load.
1964 LoadRegPlusOffsetToAt(rs); 1987 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
1965 GenInstrImmediate(LBU, at, rd, 0); // Equiv to lbu(rd, MemOperand(at, 0)); 1988 GenInstrImmediate(LBU, at, rd, off16);
1966 } 1989 }
1967 } 1990 }
1968 1991
1969 1992
1970 void Assembler::lh(Register rd, const MemOperand& rs) { 1993 void Assembler::lh(Register rd, const MemOperand& rs) {
1971 if (is_int16(rs.offset_)) { 1994 if (is_int16(rs.offset_)) {
1972 GenInstrImmediate(LH, rs.rm(), rd, rs.offset_); 1995 GenInstrImmediate(LH, rs.rm(), rd, rs.offset_);
1973 } else { // Offset > 16 bits, use multiple instructions to load. 1996 } else { // Offset > 16 bits, use multiple instructions to load.
1974 LoadRegPlusOffsetToAt(rs); 1997 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
1975 GenInstrImmediate(LH, at, rd, 0); // Equiv to lh(rd, MemOperand(at, 0)); 1998 GenInstrImmediate(LH, at, rd, off16);
1976 } 1999 }
1977 } 2000 }
1978 2001
1979 2002
1980 void Assembler::lhu(Register rd, const MemOperand& rs) { 2003 void Assembler::lhu(Register rd, const MemOperand& rs) {
1981 if (is_int16(rs.offset_)) { 2004 if (is_int16(rs.offset_)) {
1982 GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_); 2005 GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_);
1983 } else { // Offset > 16 bits, use multiple instructions to load. 2006 } else { // Offset > 16 bits, use multiple instructions to load.
1984 LoadRegPlusOffsetToAt(rs); 2007 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
1985 GenInstrImmediate(LHU, at, rd, 0); // Equiv to lhu(rd, MemOperand(at, 0)); 2008 GenInstrImmediate(LHU, at, rd, off16);
1986 } 2009 }
1987 } 2010 }
1988 2011
1989 2012
1990 void Assembler::lw(Register rd, const MemOperand& rs) { 2013 void Assembler::lw(Register rd, const MemOperand& rs) {
1991 if (is_int16(rs.offset_)) { 2014 if (is_int16(rs.offset_)) {
1992 GenInstrImmediate(LW, rs.rm(), rd, rs.offset_); 2015 GenInstrImmediate(LW, rs.rm(), rd, rs.offset_);
1993 } else { // Offset > 16 bits, use multiple instructions to load. 2016 } else { // Offset > 16 bits, use multiple instructions to load.
1994 LoadRegPlusOffsetToAt(rs); 2017 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
1995 GenInstrImmediate(LW, at, rd, 0); // Equiv to lw(rd, MemOperand(at, 0)); 2018 GenInstrImmediate(LW, at, rd, off16);
1996 } 2019 }
1997 } 2020 }
1998 2021
1999 2022
2000 void Assembler::lwu(Register rd, const MemOperand& rs) { 2023 void Assembler::lwu(Register rd, const MemOperand& rs) {
2001 if (is_int16(rs.offset_)) { 2024 if (is_int16(rs.offset_)) {
2002 GenInstrImmediate(LWU, rs.rm(), rd, rs.offset_); 2025 GenInstrImmediate(LWU, rs.rm(), rd, rs.offset_);
2003 } else { // Offset > 16 bits, use multiple instructions to load. 2026 } else { // Offset > 16 bits, use multiple instructions to load.
2004 LoadRegPlusOffsetToAt(rs); 2027 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
2005 GenInstrImmediate(LWU, at, rd, 0); // Equiv to lwu(rd, MemOperand(at, 0)); 2028 GenInstrImmediate(LWU, at, rd, off16);
2006 } 2029 }
2007 } 2030 }
2008 2031
2009 2032
2010 void Assembler::lwl(Register rd, const MemOperand& rs) { 2033 void Assembler::lwl(Register rd, const MemOperand& rs) {
2011 DCHECK(is_int16(rs.offset_)); 2034 DCHECK(is_int16(rs.offset_));
2012 DCHECK(kArchVariant == kMips64r2); 2035 DCHECK(kArchVariant == kMips64r2);
2013 GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_); 2036 GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_);
2014 } 2037 }
2015 2038
2016 2039
2017 void Assembler::lwr(Register rd, const MemOperand& rs) { 2040 void Assembler::lwr(Register rd, const MemOperand& rs) {
2018 DCHECK(is_int16(rs.offset_)); 2041 DCHECK(is_int16(rs.offset_));
2019 DCHECK(kArchVariant == kMips64r2); 2042 DCHECK(kArchVariant == kMips64r2);
2020 GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_); 2043 GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_);
2021 } 2044 }
2022 2045
2023 2046
2024 void Assembler::sb(Register rd, const MemOperand& rs) { 2047 void Assembler::sb(Register rd, const MemOperand& rs) {
2025 if (is_int16(rs.offset_)) { 2048 if (is_int16(rs.offset_)) {
2026 GenInstrImmediate(SB, rs.rm(), rd, rs.offset_); 2049 GenInstrImmediate(SB, rs.rm(), rd, rs.offset_);
2027 } else { // Offset > 16 bits, use multiple instructions to store. 2050 } else { // Offset > 16 bits, use multiple instructions to store.
2028 LoadRegPlusOffsetToAt(rs); 2051 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
2029 GenInstrImmediate(SB, at, rd, 0); // Equiv to sb(rd, MemOperand(at, 0)); 2052 GenInstrImmediate(SB, at, rd, off16);
2030 } 2053 }
2031 } 2054 }
2032 2055
2033 2056
2034 void Assembler::sh(Register rd, const MemOperand& rs) { 2057 void Assembler::sh(Register rd, const MemOperand& rs) {
2035 if (is_int16(rs.offset_)) { 2058 if (is_int16(rs.offset_)) {
2036 GenInstrImmediate(SH, rs.rm(), rd, rs.offset_); 2059 GenInstrImmediate(SH, rs.rm(), rd, rs.offset_);
2037 } else { // Offset > 16 bits, use multiple instructions to store. 2060 } else { // Offset > 16 bits, use multiple instructions to store.
2038 LoadRegPlusOffsetToAt(rs); 2061 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
2039 GenInstrImmediate(SH, at, rd, 0); // Equiv to sh(rd, MemOperand(at, 0)); 2062 GenInstrImmediate(SH, at, rd, off16);
2040 } 2063 }
2041 } 2064 }
2042 2065
2043 2066
2044 void Assembler::sw(Register rd, const MemOperand& rs) { 2067 void Assembler::sw(Register rd, const MemOperand& rs) {
2045 if (is_int16(rs.offset_)) { 2068 if (is_int16(rs.offset_)) {
2046 GenInstrImmediate(SW, rs.rm(), rd, rs.offset_); 2069 GenInstrImmediate(SW, rs.rm(), rd, rs.offset_);
2047 } else { // Offset > 16 bits, use multiple instructions to store. 2070 } else { // Offset > 16 bits, use multiple instructions to store.
2048 LoadRegPlusOffsetToAt(rs); 2071 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
2049 GenInstrImmediate(SW, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0)); 2072 GenInstrImmediate(SW, at, rd, off16);
2050 } 2073 }
2051 } 2074 }
2052 2075
2053 2076
2054 void Assembler::swl(Register rd, const MemOperand& rs) { 2077 void Assembler::swl(Register rd, const MemOperand& rs) {
2055 DCHECK(is_int16(rs.offset_)); 2078 DCHECK(is_int16(rs.offset_));
2056 DCHECK(kArchVariant == kMips64r2); 2079 DCHECK(kArchVariant == kMips64r2);
2057 GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_); 2080 GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_);
2058 } 2081 }
2059 2082
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2123 DCHECK(is_int16(rs.offset_)); 2146 DCHECK(is_int16(rs.offset_));
2124 DCHECK(kArchVariant == kMips64r2); 2147 DCHECK(kArchVariant == kMips64r2);
2125 GenInstrImmediate(SDR, rs.rm(), rd, rs.offset_); 2148 GenInstrImmediate(SDR, rs.rm(), rd, rs.offset_);
2126 } 2149 }
2127 2150
2128 2151
2129 void Assembler::ld(Register rd, const MemOperand& rs) { 2152 void Assembler::ld(Register rd, const MemOperand& rs) {
2130 if (is_int16(rs.offset_)) { 2153 if (is_int16(rs.offset_)) {
2131 GenInstrImmediate(LD, rs.rm(), rd, rs.offset_); 2154 GenInstrImmediate(LD, rs.rm(), rd, rs.offset_);
2132 } else { // Offset > 16 bits, use multiple instructions to load. 2155 } else { // Offset > 16 bits, use multiple instructions to load.
2133 LoadRegPlusOffsetToAt(rs); 2156 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
2134 GenInstrImmediate(LD, at, rd, 0); // Equiv to lw(rd, MemOperand(at, 0)); 2157 GenInstrImmediate(LD, at, rd, off16);
2135 } 2158 }
2136 } 2159 }
2137 2160
2138 2161
2139 void Assembler::sd(Register rd, const MemOperand& rs) { 2162 void Assembler::sd(Register rd, const MemOperand& rs) {
2140 if (is_int16(rs.offset_)) { 2163 if (is_int16(rs.offset_)) {
2141 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_); 2164 GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
2142 } else { // Offset > 16 bits, use multiple instructions to store. 2165 } else { // Offset > 16 bits, use multiple instructions to store.
2143 LoadRegPlusOffsetToAt(rs); 2166 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
2144 GenInstrImmediate(SD, at, rd, 0); // Equiv to sw(rd, MemOperand(at, 0)); 2167 GenInstrImmediate(SD, at, rd, off16);
2145 } 2168 }
2146 } 2169 }
2147 2170
2148 2171
2149 // ---------PC-Relative instructions----------- 2172 // ---------PC-Relative instructions-----------
2150 2173
2151 void Assembler::addiupc(Register rs, int32_t imm19) { 2174 void Assembler::addiupc(Register rs, int32_t imm19) {
2152 DCHECK(kArchVariant == kMips64r6); 2175 DCHECK(kArchVariant == kMips64r6);
2153 DCHECK(rs.is_valid() && is_int19(imm19)); 2176 DCHECK(rs.is_valid() && is_int19(imm19));
2154 uint32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask); 2177 uint32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask);
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEB, BSHFL); 2567 GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEB, BSHFL);
2545 } 2568 }
2546 2569
2547 // --------Coprocessor-instructions---------------- 2570 // --------Coprocessor-instructions----------------
2548 2571
2549 // Load, store, move. 2572 // Load, store, move.
2550 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { 2573 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
2551 if (is_int16(src.offset_)) { 2574 if (is_int16(src.offset_)) {
2552 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 2575 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
2553 } else { // Offset > 16 bits, use multiple instructions to load. 2576 } else { // Offset > 16 bits, use multiple instructions to load.
2554 LoadRegPlusOffsetToAt(src); 2577 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src);
2555 GenInstrImmediate(LWC1, at, fd, 0); 2578 GenInstrImmediate(LWC1, at, fd, off16);
2556 } 2579 }
2557 } 2580 }
2558 2581
2559 2582
2560 void Assembler::ldc1(FPURegister fd, const MemOperand& src) { 2583 void Assembler::ldc1(FPURegister fd, const MemOperand& src) {
2561 if (is_int16(src.offset_)) { 2584 if (is_int16(src.offset_)) {
2562 GenInstrImmediate(LDC1, src.rm(), fd, src.offset_); 2585 GenInstrImmediate(LDC1, src.rm(), fd, src.offset_);
2563 } else { // Offset > 16 bits, use multiple instructions to load. 2586 } else { // Offset > 16 bits, use multiple instructions to load.
2564 LoadRegPlusOffsetToAt(src); 2587 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src);
2565 GenInstrImmediate(LDC1, at, fd, 0); 2588 GenInstrImmediate(LDC1, at, fd, off16);
2566 } 2589 }
2567 } 2590 }
2568 2591
2569 2592
2570 void Assembler::swc1(FPURegister fd, const MemOperand& src) { 2593 void Assembler::swc1(FPURegister fd, const MemOperand& src) {
2571 if (is_int16(src.offset_)) { 2594 if (is_int16(src.offset_)) {
2572 GenInstrImmediate(SWC1, src.rm(), fd, src.offset_); 2595 GenInstrImmediate(SWC1, src.rm(), fd, src.offset_);
2573 } else { // Offset > 16 bits, use multiple instructions to load. 2596 } else { // Offset > 16 bits, use multiple instructions to load.
2574 LoadRegPlusOffsetToAt(src); 2597 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src);
2575 GenInstrImmediate(SWC1, at, fd, 0); 2598 GenInstrImmediate(SWC1, at, fd, off16);
2576 } 2599 }
2577 } 2600 }
2578 2601
2579 2602
2580 void Assembler::sdc1(FPURegister fd, const MemOperand& src) { 2603 void Assembler::sdc1(FPURegister fd, const MemOperand& src) {
2581 DCHECK(!src.rm().is(at)); 2604 DCHECK(!src.rm().is(at));
2582 if (is_int16(src.offset_)) { 2605 if (is_int16(src.offset_)) {
2583 GenInstrImmediate(SDC1, src.rm(), fd, src.offset_); 2606 GenInstrImmediate(SDC1, src.rm(), fd, src.offset_);
2584 } else { // Offset > 16 bits, use multiple instructions to load. 2607 } else { // Offset > 16 bits, use multiple instructions to load.
2585 LoadRegPlusOffsetToAt(src); 2608 int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src);
2586 GenInstrImmediate(SDC1, at, fd, 0); 2609 GenInstrImmediate(SDC1, at, fd, off16);
2587 } 2610 }
2588 } 2611 }
2589 2612
2590 2613
2591 void Assembler::mtc1(Register rt, FPURegister fs) { 2614 void Assembler::mtc1(Register rt, FPURegister fs) {
2592 GenInstrRegister(COP1, MTC1, rt, fs, f0); 2615 GenInstrRegister(COP1, MTC1, rt, fs, f0);
2593 } 2616 }
2594 2617
2595 2618
2596 void Assembler::mthc1(Register rt, FPURegister fs) { 2619 void Assembler::mthc1(Register rt, FPURegister fs) {
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after
3482 3505
3483 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 3506 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
3484 Assembler::FlushICache(isolate, pc, 4 * Assembler::kInstrSize); 3507 Assembler::FlushICache(isolate, pc, 4 * Assembler::kInstrSize);
3485 } 3508 }
3486 } 3509 }
3487 3510
3488 } // namespace internal 3511 } // namespace internal
3489 } // namespace v8 3512 } // namespace v8
3490 3513
3491 #endif // V8_TARGET_ARCH_MIPS64 3514 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/assembler-mips64.h ('k') | test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698