import Unicorn2
This commit is contained in:
@ -23,8 +23,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unicorn/platform.h"
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/host-utils.h"
|
||||
|
||||
#ifndef CONFIG_INT128
|
||||
@ -54,10 +53,10 @@ static inline void mul64(uint64_t *plow, uint64_t *phigh,
|
||||
rh.ll = (uint64_t)a0.l.high * b0.l.high;
|
||||
|
||||
c = (uint64_t)rl.l.high + rm.l.low + rn.l.low;
|
||||
rl.l.high = (uint32_t)c;
|
||||
rl.l.high = c;
|
||||
c >>= 32;
|
||||
c = c + rm.l.high + rn.l.high + rh.l.low;
|
||||
rh.l.low = (uint32_t)c;
|
||||
rh.l.low = c;
|
||||
rh.l.high += (uint32_t)(c >> 32);
|
||||
|
||||
*plow = rl.ll;
|
||||
@ -160,8 +159,69 @@ int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
|
||||
|
||||
return overflow;
|
||||
}
|
||||
#else
|
||||
// avoid empty object file
|
||||
void dummy_func(void);
|
||||
void dummy_func(void) {}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* urshift - 128-bit Unsigned Right Shift.
|
||||
* @plow: in/out - lower 64-bit integer.
|
||||
* @phigh: in/out - higher 64-bit integer.
|
||||
* @shift: in - bytes to shift, between 0 and 127.
|
||||
*
|
||||
* Result is zero-extended and stored in plow/phigh, which are
|
||||
* input/output variables. Shift values outside the range will
|
||||
* be mod to 128. In other words, the caller is responsible to
|
||||
* verify/assert both the shift range and plow/phigh pointers.
|
||||
*/
|
||||
void urshift(uint64_t *plow, uint64_t *phigh, int32_t shift)
|
||||
{
|
||||
shift &= 127;
|
||||
if (shift == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t h = *phigh >> (shift & 63);
|
||||
if (shift >= 64) {
|
||||
*plow = h;
|
||||
*phigh = 0;
|
||||
} else {
|
||||
*plow = (*plow >> (shift & 63)) | (*phigh << (64 - (shift & 63)));
|
||||
*phigh = h;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ulshift - 128-bit Unsigned Left Shift.
|
||||
* @plow: in/out - lower 64-bit integer.
|
||||
* @phigh: in/out - higher 64-bit integer.
|
||||
* @shift: in - bytes to shift, between 0 and 127.
|
||||
* @overflow: out - true if any 1-bit is shifted out.
|
||||
*
|
||||
* Result is zero-extended and stored in plow/phigh, which are
|
||||
* input/output variables. Shift values outside the range will
|
||||
* be mod to 128. In other words, the caller is responsible to
|
||||
* verify/assert both the shift range and plow/phigh pointers.
|
||||
*/
|
||||
void ulshift(uint64_t *plow, uint64_t *phigh, int32_t shift, bool *overflow)
|
||||
{
|
||||
uint64_t low = *plow;
|
||||
uint64_t high = *phigh;
|
||||
|
||||
shift &= 127;
|
||||
if (shift == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if any bit will be shifted out */
|
||||
urshift(&low, &high, 128 - shift);
|
||||
if (low | high) {
|
||||
*overflow = true;
|
||||
}
|
||||
|
||||
if (shift >= 64) {
|
||||
*phigh = *plow << (shift & 63);
|
||||
*plow = 0;
|
||||
} else {
|
||||
*phigh = (*plow >> (64 - (shift & 63))) | (*phigh << (shift & 63));
|
||||
*plow = *plow << shift;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user