OLD | NEW |
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 | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are 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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 ScaleFactor scale, | 275 ScaleFactor scale, |
276 int32_t disp, | 276 int32_t disp, |
277 RelocInfo::Mode rmode) { | 277 RelocInfo::Mode rmode) { |
278 DCHECK(!index.is(esp)); // illegal addressing mode | 278 DCHECK(!index.is(esp)); // illegal addressing mode |
279 // [index*scale + disp/r] | 279 // [index*scale + disp/r] |
280 set_modrm(0, esp); | 280 set_modrm(0, esp); |
281 set_sib(scale, index, ebp); | 281 set_sib(scale, index, ebp); |
282 set_dispr(disp, rmode); | 282 set_dispr(disp, rmode); |
283 } | 283 } |
284 | 284 |
| 285 Operand::Operand(const Operand& operand, int32_t offset) { |
| 286 DCHECK(operand.len_ >= 1); |
| 287 // Operand encodes REX ModR/M [SIB] [Disp]. |
| 288 byte modrm = operand.buf_[0]; |
| 289 DCHECK(modrm < 0xC0); // Disallow mode 3 (register target). |
| 290 bool has_sib = ((modrm & 0x07) == 0x04); |
| 291 byte mode = modrm & 0xC0; |
| 292 int disp_offset = has_sib ? 2 : 1; |
| 293 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07; |
| 294 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit |
| 295 // displacement. |
| 296 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base. |
| 297 int32_t disp_value = 0; |
| 298 if (mode == 0x80 || is_baseless) { |
| 299 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement. |
| 300 disp_value = *bit_cast<const int32_t*>(&operand.buf_[disp_offset]); |
| 301 } else if (mode == 0x40) { |
| 302 // Mode 1: Byte displacement. |
| 303 disp_value = static_cast<signed char>(operand.buf_[disp_offset]); |
| 304 } |
| 305 |
| 306 // Write new operand with same registers, but with modified displacement. |
| 307 DCHECK(offset >= 0 ? disp_value + offset >= disp_value |
| 308 : disp_value + offset < disp_value); // No overflow. |
| 309 disp_value += offset; |
| 310 if (!is_int8(disp_value) || is_baseless) { |
| 311 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13. |
| 312 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80); |
| 313 len_ = disp_offset + 4; |
| 314 Memory::int32_at(&buf_[disp_offset]) = disp_value; |
| 315 } else if (disp_value != 0 || (base_reg == 0x05)) { |
| 316 // Need 8 bits of displacement. |
| 317 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1. |
| 318 len_ = disp_offset + 1; |
| 319 buf_[disp_offset] = static_cast<byte>(disp_value); |
| 320 } else { |
| 321 // Need no displacement. |
| 322 buf_[0] = (modrm & 0x3f); // Mode 0. |
| 323 len_ = disp_offset; |
| 324 } |
| 325 if (has_sib) { |
| 326 buf_[1] = operand.buf_[1]; |
| 327 } |
| 328 } |
285 | 329 |
286 bool Operand::is_reg(Register reg) const { | 330 bool Operand::is_reg(Register reg) const { |
287 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. | 331 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. |
288 && ((buf_[0] & 0x07) == reg.code()); // register codes match. | 332 && ((buf_[0] & 0x07) == reg.code()); // register codes match. |
289 } | 333 } |
290 | 334 |
291 | 335 |
292 bool Operand::is_reg_only() const { | 336 bool Operand::is_reg_only() const { |
293 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. | 337 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. |
294 } | 338 } |
(...skipping 2562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2857 DCHECK(IsEnabled(BMI2)); | 2901 DCHECK(IsEnabled(BMI2)); |
2858 DCHECK(is_uint8(imm8)); | 2902 DCHECK(is_uint8(imm8)); |
2859 Register vreg = {0}; // VEX.vvvv unused | 2903 Register vreg = {0}; // VEX.vvvv unused |
2860 EnsureSpace ensure_space(this); | 2904 EnsureSpace ensure_space(this); |
2861 emit_vex_prefix(vreg, kLZ, kF2, k0F3A, kW0); | 2905 emit_vex_prefix(vreg, kLZ, kF2, k0F3A, kW0); |
2862 EMIT(0xF0); | 2906 EMIT(0xF0); |
2863 emit_operand(dst, src); | 2907 emit_operand(dst, src); |
2864 EMIT(imm8); | 2908 EMIT(imm8); |
2865 } | 2909 } |
2866 | 2910 |
| 2911 void Assembler::movups(XMMRegister dst, const Operand& src) { |
| 2912 EnsureSpace ensure_space(this); |
| 2913 EMIT(0x0F); |
| 2914 EMIT(0x10); |
| 2915 emit_sse_operand(dst, src); |
| 2916 } |
| 2917 |
| 2918 void Assembler::movups(const Operand& dst, XMMRegister src) { |
| 2919 EnsureSpace ensure_space(this); |
| 2920 EMIT(0x0F); |
| 2921 EMIT(0x11); |
| 2922 emit_sse_operand(src, dst); |
| 2923 } |
| 2924 |
| 2925 void Assembler::minps(XMMRegister dst, const Operand& src) { |
| 2926 EnsureSpace ensure_space(this); |
| 2927 EMIT(0x0F); |
| 2928 EMIT(0x5D); |
| 2929 emit_sse_operand(dst, src); |
| 2930 } |
| 2931 |
| 2932 void Assembler::maxps(XMMRegister dst, const Operand& src) { |
| 2933 EnsureSpace ensure_space(this); |
| 2934 EMIT(0x0F); |
| 2935 EMIT(0x5F); |
| 2936 emit_sse_operand(dst, src); |
| 2937 } |
| 2938 |
| 2939 void Assembler::rcpps(XMMRegister dst, const Operand& src) { |
| 2940 EnsureSpace ensure_space(this); |
| 2941 EMIT(0x0F); |
| 2942 EMIT(0x53); |
| 2943 emit_sse_operand(dst, src); |
| 2944 } |
| 2945 |
| 2946 void Assembler::rsqrtps(XMMRegister dst, const Operand& src) { |
| 2947 EnsureSpace ensure_space(this); |
| 2948 EMIT(0x0F); |
| 2949 EMIT(0x52); |
| 2950 emit_sse_operand(dst, src); |
| 2951 } |
| 2952 |
| 2953 void Assembler::sqrtps(XMMRegister dst, const Operand& src) { |
| 2954 EnsureSpace ensure_space(this); |
| 2955 EMIT(0x0F); |
| 2956 EMIT(0x51); |
| 2957 emit_sse_operand(dst, src); |
| 2958 } |
| 2959 |
| 2960 void Assembler::cvtdq2ps(XMMRegister dst, const Operand& src) { |
| 2961 EnsureSpace ensure_space(this); |
| 2962 EMIT(0x0F); |
| 2963 EMIT(0x5B); |
| 2964 emit_sse_operand(dst, src); |
| 2965 } |
| 2966 |
| 2967 void Assembler::paddd(XMMRegister dst, const Operand& src) { |
| 2968 EnsureSpace ensure_space(this); |
| 2969 EMIT(0x66); |
| 2970 EMIT(0x0F); |
| 2971 EMIT(0xFE); |
| 2972 emit_sse_operand(dst, src); |
| 2973 } |
| 2974 |
| 2975 void Assembler::psubd(XMMRegister dst, const Operand& src) { |
| 2976 EnsureSpace ensure_space(this); |
| 2977 EMIT(0x66); |
| 2978 EMIT(0x0F); |
| 2979 EMIT(0xFA); |
| 2980 emit_sse_operand(dst, src); |
| 2981 } |
| 2982 |
| 2983 void Assembler::pmulld(XMMRegister dst, const Operand& src) { |
| 2984 DCHECK(IsEnabled(SSE4_1)); |
| 2985 EnsureSpace ensure_space(this); |
| 2986 EMIT(0x66); |
| 2987 EMIT(0x0F); |
| 2988 EMIT(0x38); |
| 2989 EMIT(0x40); |
| 2990 emit_sse_operand(dst, src); |
| 2991 } |
| 2992 |
| 2993 void Assembler::pmuludq(XMMRegister dst, const Operand& src) { |
| 2994 EnsureSpace ensure_space(this); |
| 2995 EMIT(0x66); |
| 2996 EMIT(0x0F); |
| 2997 EMIT(0xF4); |
| 2998 emit_sse_operand(dst, src); |
| 2999 } |
| 3000 |
| 3001 void Assembler::punpackldq(XMMRegister dst, const Operand& src) { |
| 3002 EnsureSpace ensure_space(this); |
| 3003 EMIT(0x66); |
| 3004 EMIT(0x0F); |
| 3005 EMIT(0x62); |
| 3006 emit_sse_operand(dst, src); |
| 3007 } |
| 3008 |
| 3009 void Assembler::cvtps2dq(XMMRegister dst, const Operand& src) { |
| 3010 EnsureSpace ensure_space(this); |
| 3011 EMIT(0x66); |
| 3012 EMIT(0x0F); |
| 3013 EMIT(0x5B); |
| 3014 emit_sse_operand(dst, src); |
| 3015 } |
| 3016 |
| 3017 void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) { |
| 3018 EnsureSpace ensure_space(this); |
| 3019 EMIT(0x0F); |
| 3020 EMIT(0xC2); |
| 3021 emit_sse_operand(dst, src); |
| 3022 EMIT(cmp); |
| 3023 } |
| 3024 |
| 3025 void Assembler::cmpeqps(XMMRegister dst, XMMRegister src) { |
| 3026 cmpps(dst, src, 0x0); |
| 3027 } |
| 3028 |
| 3029 void Assembler::cmpltps(XMMRegister dst, XMMRegister src) { |
| 3030 cmpps(dst, src, 0x1); |
| 3031 } |
| 3032 |
| 3033 void Assembler::cmpleps(XMMRegister dst, XMMRegister src) { |
| 3034 cmpps(dst, src, 0x2); |
| 3035 } |
| 3036 |
| 3037 void Assembler::cmpneqps(XMMRegister dst, XMMRegister src) { |
| 3038 cmpps(dst, src, 0x4); |
| 3039 } |
| 3040 |
| 3041 void Assembler::cmpnltps(XMMRegister dst, XMMRegister src) { |
| 3042 cmpps(dst, src, 0x5); |
| 3043 } |
| 3044 |
| 3045 void Assembler::cmpnleps(XMMRegister dst, XMMRegister src) { |
| 3046 cmpps(dst, src, 0x6); |
| 3047 } |
| 3048 |
| 3049 void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) { |
| 3050 DCHECK(CpuFeatures::IsSupported(SSE4_1)); |
| 3051 DCHECK(is_uint8(imm8)); |
| 3052 EnsureSpace ensure_space(this); |
| 3053 EMIT(0x66); |
| 3054 EMIT(0x0F); |
| 3055 EMIT(0x3A); |
| 3056 EMIT(0x21); |
| 3057 emit_sse_operand(dst, src); |
| 3058 EMIT(imm8); |
| 3059 } |
2867 | 3060 |
2868 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { | 3061 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { |
2869 Register ireg = { reg.code() }; | 3062 Register ireg = { reg.code() }; |
2870 emit_operand(ireg, adr); | 3063 emit_operand(ireg, adr); |
2871 } | 3064 } |
2872 | 3065 |
2873 | 3066 |
2874 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { | 3067 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { |
2875 EMIT(0xC0 | dst.code() << 3 | src.code()); | 3068 EMIT(0xC0 | dst.code() << 3 | src.code()); |
2876 } | 3069 } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3088 fflush(coverage_log); | 3281 fflush(coverage_log); |
3089 } | 3282 } |
3090 } | 3283 } |
3091 | 3284 |
3092 #endif | 3285 #endif |
3093 | 3286 |
3094 } // namespace internal | 3287 } // namespace internal |
3095 } // namespace v8 | 3288 } // namespace v8 |
3096 | 3289 |
3097 #endif // V8_TARGET_ARCH_IA32 | 3290 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |