]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/Ebc/Dxe/x64/x64Math.c
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@905 6f19259b...
[mirror_edk2.git] / EdkModulePkg / Universal / Ebc / Dxe / x64 / x64Math.c
CommitLineData
878ddf1f 1/*++\r
2\r
abf537ea 3Copyright (c) 2006, Intel Corporation.\r
878ddf1f 4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 x64math.c\r
15\r
16Abstract:\r
17\r
18 Math routines for x64.\r
19\r
20--*/\r
21\r
22UINT64\r
23LeftShiftU64 (\r
24 IN UINT64 Operand,\r
25 IN UINT64 Count\r
26 )\r
27/*++\r
28\r
29Routine Description:\r
30 \r
31 Left-shift a 64 bit value.\r
32\r
33Arguments:\r
34\r
35 Operand - 64-bit value to shift\r
36 Count - shift count\r
37\r
38Returns:\r
39\r
40 Operand << Count\r
41\r
42--*/\r
43{\r
44 if (Count > 63) {\r
45 return 0;\r
46 }\r
47\r
48 return Operand << Count;\r
49}\r
50\r
51UINT64\r
52RightShiftU64 (\r
53 IN UINT64 Operand,\r
54 IN UINT64 Count\r
55 )\r
56/*++\r
57\r
58Routine Description:\r
59 \r
60 Right-shift a 64 bit value.\r
61\r
62Arguments:\r
63\r
64 Operand - 64-bit value to shift\r
65 Count - shift count\r
66\r
67Returns:\r
68\r
69 Operand >> Count\r
70\r
71--*/\r
72{\r
73 if (Count > 63) {\r
74 return 0;\r
75 }\r
76\r
77 return Operand >> Count;\r
78}\r
79\r
80INT64\r
81ARightShift64 (\r
82 IN INT64 Operand,\r
83 IN UINT64 Count\r
84 )\r
85/*++\r
86\r
87Routine Description:\r
88 \r
89 Right-shift a 64 bit signed value.\r
90\r
91Arguments:\r
92\r
93 Operand - 64-bit value to shift\r
94 Count - shift count\r
95\r
96Returns:\r
97\r
98 Operand >> Count\r
99\r
100--*/\r
101{\r
102 if (Count > 63) {\r
103\r
104 if (Operand & 0x8000000000000000ULL) {\r
105 return (INT64)~0;\r
106 }\r
107\r
108 return 0;\r
109 }\r
110\r
111 return Operand >> Count;\r
112}\r
113\r
114#if 0\r
115//\r
116// The compiler generates true assembly for these, so we don't need them.\r
117//\r
118INT32\r
119ARightShift32 (\r
120 IN INT32 Operand,\r
121 IN UINTN Count\r
122 )\r
123/*++\r
124\r
125Routine Description:\r
126 \r
127 Right shift a 32-bit value\r
128\r
129Arguments:\r
130\r
131 Operand - value to shift\r
132 Count - shift count\r
133\r
134Returns:\r
135\r
136 Operand >> Count\r
137\r
138--*/\r
139{\r
140 return Operand >> (Count & 0x1f);\r
141}\r
142\r
143INT32\r
144MulS32x32 (\r
145 INT32 Value1,\r
146 INT32 Value2,\r
147 INT32 *ResultHigh\r
148 )\r
149/*++\r
150\r
151Routine Description:\r
152 \r
153 Multiply two signed 32-bit numbers.\r
154\r
155Arguments:\r
156\r
157 Value1 - first value to multiply\r
158 Value2 - value to multiply Value1 by\r
159 ResultHigh - overflow\r
160\r
161Returns:\r
162\r
163 Value1 * Value2\r
164\r
165Notes:\r
166\r
167 The 64-bit result is the concatenation of *ResultHigh and the return value\r
168\r
169 The product fits in 32 bits if\r
170 (*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)\r
171 OR\r
172 (*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)\r
173\r
174--*/\r
175{\r
176 INT64 Rres64;\r
177 INT32 Result;\r
178\r
179 Res64 = (INT64) Value1 * (INT64) Value2;\r
180 *ResultHigh = (Res64 >> 32) & 0xffffffff;\r
181 Result = Res64 & 0xffffffff;\r
182 return Result;\r
183}\r
184\r
185UINT32\r
186MulU32x32 (\r
187 UINT32 Value1,\r
188 UINT32 Value2,\r
189 UINT32 *ResultHigh\r
190 )\r
191/*++\r
192\r
193Routine Description:\r
194 \r
195 Multiply two unsigned 32-bit values.\r
196\r
197Arguments:\r
198\r
199 Value1 - first number\r
200 Value2 - number to multiply by Value1 \r
201 ResultHigh - overflow\r
202\r
203Returns:\r
204\r
205 Value1 * Value2\r
206\r
207Notes:\r
208\r
209 The 64-bit result is the concatenation of *ResultHigh and the return value.\r
210 The product fits in 32 bits if *ResultHigh == 0x00000000\r
211\r
212--*/\r
213{\r
214 UINT64 Res64;\r
215 UINT32 Result;\r
216\r
217 Res64 = (INT64) Value1 * (INT64) Value2;\r
218 *ResultHigh = (Res64 >> 32) & 0xffffffff;\r
219 Result = Res64 & 0xffffffff;\r
220 return Result;\r
221}\r
222\r
223INT32\r
224DivS32x32 (\r
225 INT32 Value1,\r
226 INT32 Value2,\r
227 INT32 *Remainder,\r
228 UINTN *error\r
229 )\r
230//\r
231// signed 32-bit by signed 32-bit divide; the 32-bit remainder is\r
232// in *Remainder and the quotient is the return value; *error = 1 if the\r
233// divisor is 0, and it is 1 otherwise\r
234//\r
235{\r
236 INT32 Result;\r
237\r
238 *error = 0;\r
239\r
240 if (Value2 == 0x0) {\r
241 *error = 1;\r
242 Result = 0x80000000;\r
243 *Remainder = 0x80000000;\r
244 } else {\r
245 Result = Value1 / Value2;\r
246 *Remainder = Value1 - Result * Value2;\r
247 }\r
248\r
249 return Result;\r
250}\r
251\r
252UINT32\r
253DivU32x32 (\r
254 UINT32 Value1,\r
255 UINT32 Value2,\r
256 UINT32 *Remainder,\r
257 UINTN *Error\r
258 )\r
259//\r
260// unsigned 32-bit by unsigned 32-bit divide; the 32-bit remainder is\r
261// in *Remainder and the quotient is the return value; *error = 1 if the\r
262// divisor is 0, and it is 1 otherwise\r
263//\r
264{\r
265 UINT32 Result;\r
266\r
267 *Error = 0;\r
268\r
269 if (Value2 == 0x0) {\r
270 *Error = 1;\r
271 Result = 0x80000000;\r
272 *Remainder = 0x80000000;\r
273 } else {\r
274 Result = Value1 / Value2;\r
275 *Remainder = Value1 - Result * Value2;\r
276 }\r
277\r
278 return Result;\r
279}\r
280\r
281#endif\r
282\r
283INT64\r
284MulS64x64 (\r
285 INT64 Value1,\r
286 INT64 Value2,\r
287 INT64 *ResultHigh\r
288 )\r
289/*++\r
290\r
291Routine Description:\r
292 \r
293 Multiply two signed 32-bit numbers.\r
294\r
295Arguments:\r
296\r
297 Value1 - first value to multiply\r
298 Value2 - value to multiply Value1 by\r
299 ResultHigh - overflow\r
300\r
301Returns:\r
302\r
303 Value1 * Value2\r
304\r
305Notes:\r
306\r
307 The 64-bit result is the concatenation of *ResultHigh and the return value\r
308\r
309 The product fits in 32 bits if\r
310 (*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)\r
311 OR\r
312 (*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)\r
313\r
314--*/\r
315{\r
316 INT64 Result;\r
317 \r
318 Result = Value1 * Value2;\r
319\r
320 return Result;\r
321}\r
322\r
323UINT64\r
324MulU64x64 (\r
325 UINT64 Value1,\r
326 UINT64 Value2,\r
327 UINT64 *ResultHigh\r
328 )\r
329/*++\r
330\r
331Routine Description:\r
332 \r
333 Multiply two unsigned 32-bit values.\r
334\r
335Arguments:\r
336\r
337 Value1 - first number\r
338 Value2 - number to multiply by Value1 \r
339 ResultHigh - overflow\r
340\r
341Returns:\r
342\r
343 Value1 * Value2\r
344\r
345Notes:\r
346\r
347 The 64-bit result is the concatenation of *ResultHigh and the return value.\r
348 The product fits in 32 bits if *ResultHigh == 0x00000000\r
349\r
350--*/\r
351{\r
352 UINT64 Result;\r
353\r
354 Result = Value1 * Value2;\r
355\r
356 return Result;\r
357}\r
358\r
359INT64\r
360DivS64x64 (\r
361 INT64 Value1,\r
362 INT64 Value2,\r
363 INT64 *Remainder,\r
364 UINTN *Error\r
365 )\r
366/*++\r
367\r
368Routine Description:\r
369 \r
370 Divide two 64-bit signed values.\r
371\r
372Arguments:\r
373\r
374 Value1 - dividend\r
375 Value2 - divisor\r
376 Remainder - remainder of Value1/Value2\r
377 Error - to flag errors (divide-by-0)\r
378\r
379Returns:\r
380\r
381 Value1 / Valu2\r
382\r
383Note:\r
384\r
385 The 64-bit remainder is in *Remainder and the quotient is the return value.\r
386 *Error = 1 if the divisor is 0, and it is 1 otherwise\r
387\r
388--*/\r
389{\r
390 INT64 Result;\r
391\r
392 *Error = 0;\r
393\r
394 if (Value2 == 0x0) {\r
395 *Error = 1;\r
396 Result = 0x8000000000000000;\r
397 *Remainder = 0x8000000000000000;\r
398 } else {\r
399 Result = Value1 / Value2;\r
400 *Remainder = Value1 - Result * Value2;\r
401 }\r
402\r
403 return Result;\r
404}\r
405\r
406UINT64\r
407DivU64x64 (\r
408 UINT64 Value1,\r
409 UINT64 Value2,\r
410 UINT64 *Remainder,\r
411 UINTN *Error\r
412 )\r
413/*++\r
414\r
415Routine Description:\r
416 \r
417 Divide two 64-bit unsigned values.\r
418\r
419Arguments:\r
420\r
421 Value1 - dividend\r
422 Value2 - divisor\r
423 Remainder - remainder of Value1/Value2\r
424 Error - to flag errors (divide-by-0)\r
425\r
426Returns:\r
427\r
428 Value1 / Valu2\r
429\r
430Note:\r
431\r
432 The 64-bit remainder is in *Remainder and the quotient is the return value.\r
433 *Error = 1 if the divisor is 0, and it is 1 otherwise\r
434\r
435--*/\r
436{\r
437 UINT64 Result;\r
438\r
439 *Error = 0;\r
440\r
441 if (Value2 == 0x0) {\r
442 *Error = 1;\r
443 Result = 0x8000000000000000;\r
444 *Remainder = 0x8000000000000000;\r
445 } else {\r
446 Result = Value1 / Value2;\r
447 *Remainder = Value1 - Result * Value2;\r
448 }\r
449\r
450 return Result;\r
451}\r