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 } | |
329 | 285 |
330 bool Operand::is_reg(Register reg) const { | 286 bool Operand::is_reg(Register reg) const { |
331 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. | 287 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. |
332 && ((buf_[0] & 0x07) == reg.code()); // register codes match. | 288 && ((buf_[0] & 0x07) == reg.code()); // register codes match. |
333 } | 289 } |
334 | 290 |
335 | 291 |
336 bool Operand::is_reg_only() const { | 292 bool Operand::is_reg_only() const { |
337 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. | 293 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. |
338 } | 294 } |
(...skipping 2562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2901 DCHECK(IsEnabled(BMI2)); | 2857 DCHECK(IsEnabled(BMI2)); |
2902 DCHECK(is_uint8(imm8)); | 2858 DCHECK(is_uint8(imm8)); |
2903 Register vreg = {0}; // VEX.vvvv unused | 2859 Register vreg = {0}; // VEX.vvvv unused |
2904 EnsureSpace ensure_space(this); | 2860 EnsureSpace ensure_space(this); |
2905 emit_vex_prefix(vreg, kLZ, kF2, k0F3A, kW0); | 2861 emit_vex_prefix(vreg, kLZ, kF2, k0F3A, kW0); |
2906 EMIT(0xF0); | 2862 EMIT(0xF0); |
2907 emit_operand(dst, src); | 2863 emit_operand(dst, src); |
2908 EMIT(imm8); | 2864 EMIT(imm8); |
2909 } | 2865 } |
2910 | 2866 |
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 } | |
3060 | 2867 |
3061 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { | 2868 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { |
3062 Register ireg = { reg.code() }; | 2869 Register ireg = { reg.code() }; |
3063 emit_operand(ireg, adr); | 2870 emit_operand(ireg, adr); |
3064 } | 2871 } |
3065 | 2872 |
3066 | 2873 |
3067 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { | 2874 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { |
3068 EMIT(0xC0 | dst.code() << 3 | src.code()); | 2875 EMIT(0xC0 | dst.code() << 3 | src.code()); |
3069 } | 2876 } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3281 fflush(coverage_log); | 3088 fflush(coverage_log); |
3282 } | 3089 } |
3283 } | 3090 } |
3284 | 3091 |
3285 #endif | 3092 #endif |
3286 | 3093 |
3287 } // namespace internal | 3094 } // namespace internal |
3288 } // namespace v8 | 3095 } // namespace v8 |
3289 | 3096 |
3290 #endif // V8_TARGET_ARCH_IA32 | 3097 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |