1 /** 2 * Contains a memset implementation used by compiler-generated code. 3 * 4 * Copyright: Copyright Digital Mars 2004 - 2010. 5 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 * Authors: Walter Bright 7 */ 8 9 /* Copyright Digital Mars 2004 - 2010. 10 * Distributed under the Boost Software License, Version 1.0. 11 * (See accompanying file LICENSE or copy at 12 * http://www.boost.org/LICENSE_1_0.txt) 13 */ 14 module miniruntime.memset; 15 16 /* 17 In -betterC mode, the compiler should use libc's memset instead of _memset32 in Dlang's 18 runtime to init memory. However, dmd incorrectly generate _memset32, so we need to polyfill it. 19 20 Bug example: https://run.dlang.io/is/7TUsX5 21 Bug report: https://issues.dlang.org/show_bug.cgi?id=17778 22 */ 23 version(DigitalMars) { 24 25 @nogc: 26 nothrow: 27 @trusted: 28 29 extern (C) 30 { 31 // Functions from the C library. 32 void *memcpy(void *, void *, size_t); 33 } 34 35 extern (C): 36 37 short *_memset16(short *p, short value, size_t count) 38 { 39 short *pstart = p; 40 short *ptop; 41 42 for (ptop = &p[count]; p < ptop; p++) 43 *p = value; 44 return pstart; 45 } 46 47 int *_memset32(int *p, int value, size_t count) 48 { 49 version (D_InlineAsm_X86) 50 { 51 asm @nogc nothrow 52 { 53 mov EDI,p ; 54 mov EAX,value ; 55 mov ECX,count ; 56 mov EDX,EDI ; 57 rep ; 58 stosd ; 59 mov EAX,EDX ; 60 } 61 } 62 else 63 { 64 int *pstart = p; 65 int *ptop; 66 67 for (ptop = &p[count]; p < ptop; p++) 68 *p = value; 69 return pstart; 70 } 71 } 72 73 long *_memset64(long *p, long value, size_t count) 74 { 75 long *pstart = p; 76 long *ptop; 77 78 for (ptop = &p[count]; p < ptop; p++) 79 *p = value; 80 return pstart; 81 } 82 83 cdouble *_memset128(cdouble *p, cdouble value, size_t count) 84 { 85 cdouble *pstart = p; 86 cdouble *ptop; 87 88 for (ptop = &p[count]; p < ptop; p++) 89 *p = value; 90 return pstart; 91 } 92 93 void[] *_memset128ii(void[] *p, void[] value, size_t count) 94 { 95 void[] *pstart = p; 96 void[] *ptop; 97 98 for (ptop = &p[count]; p < ptop; p++) 99 *p = value; 100 return pstart; 101 } 102 103 real *_memset80(real *p, real value, size_t count) 104 { 105 real *pstart = p; 106 real *ptop; 107 108 for (ptop = &p[count]; p < ptop; p++) 109 *p = value; 110 return pstart; 111 } 112 113 creal *_memset160(creal *p, creal value, size_t count) 114 { 115 creal *pstart = p; 116 creal *ptop; 117 118 for (ptop = &p[count]; p < ptop; p++) 119 *p = value; 120 return pstart; 121 } 122 123 void *_memsetn(void *p, void *value, int count, size_t sizelem) 124 { void *pstart = p; 125 int i; 126 127 for (i = 0; i < count; i++) 128 { 129 memcpy(p, value, sizelem); 130 p = cast(void *)(cast(char *)p + sizelem); 131 } 132 return pstart; 133 } 134 135 float *_memsetFloat(float *p, float value, size_t count) 136 { 137 float *pstart = p; 138 float *ptop; 139 140 for (ptop = &p[count]; p < ptop; p++) 141 *p = value; 142 return pstart; 143 } 144 145 double *_memsetDouble(double *p, double value, size_t count) 146 { 147 double *pstart = p; 148 double *ptop; 149 150 for (ptop = &p[count]; p < ptop; p++) 151 *p = value; 152 return pstart; 153 } 154 155 version (D_SIMD) 156 { 157 import core.simd; 158 159 void16* _memsetSIMD(void16 *p, void16 value, size_t count) 160 { 161 foreach (i; 0..count) 162 p[i] = value; 163 return p; 164 } 165 } 166 }