Timeline for Shift right by half a bit
Current License: CC BY-SA 4.0
24 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jun 17, 2020 at 9:04 | history | edited | CommunityBot |
Commonmark migration
|
|
Jan 27, 2020 at 19:12 | history | edited | 640KB | CC BY-SA 4.0 |
grammar, correct max N
|
Jan 27, 2020 at 0:59 | comment | added | 640KB |
@PeterCordes Yeah, it was more that at first glance I didn't realize that I had to make a temp copy of all four words to do the bitshifts (or add -> adc ) separately. Though mine ended up being more like ((y=x+x)<<2)+y+new_digit . I did change the RCL 's to ADD /ADC after I posted that scratchpad link. Anyway, everything's working great for both input and output of 64 bit values in ASCII on x86-16!
|
|
Jan 27, 2020 at 0:49 | history | edited | 640KB | CC BY-SA 4.0 |
added 96 characters in body
|
Jan 26, 2020 at 21:41 | comment | added | Peter Cordes |
Yes, saving the x<<1 somewhere while doing the <<3 is what I had in mind. But multi-precision shifts are relatively easy and cheap (vs. extended-precision mul ) with add same,same -> adc same,same , or by 3 bits at a time with 386 shld /.../shl starting from the top. That's why I broke down the usual total = total*10 + c - '0' that way, instead of the usual x *5 *2 for a single-register total, with lea reg, [reg + reg*4] and lea reg, [new_digit + reg*2] if 32/64-bit addressing modes are available. (My SO answer)
|
|
Jan 26, 2020 at 21:05 | comment | added | 640KB |
@PeterCordes I like your algorithm for input, though trickier than it seems on the surface because you're also doing carry propagation on the two bitshifted copies of x as well as the later addition. Here's what I came up with godbolt.org/z/yqVp3- (still needs to be adapted to allow for negative decimal inputs, but that's not the interesting part). Thx yet again for the pro tips!
|
|
Jan 26, 2020 at 18:29 | history | edited | 640KB | CC BY-SA 4.0 |
deleted 339 characters in body
|
Jan 26, 2020 at 16:10 | comment | added | 640KB | @PeterCordes I have some routines for 32 bit to ascii, and just never needed to extend them to 64. I do like this routine since it's very clean (and took no time to adapt for signed!). And yes, just need to wrap up the inverse and the cycle will be complete! Thanks for the links! | |
Jan 26, 2020 at 2:20 | comment | added | Peter Cordes |
If you want it: How to display a 64 bit number in decimal in assembly 8086 for output, using only 8086 instructions. Or in 16-bit mode on an emulator like DOSBox, you can use div r32 (32-bit regs in 16-bit mode). Then simply adapt Print 64 bit number stored in EDX:EAX to standard out. Input is easier, e.g. (x << 3) + (x<<1) + new_digit with carry propagation across 2 or 4 limbs. Or use hex; that's still trivial for large values and you can even use SSSE3 in real mode :P
|
|
Jan 26, 2020 at 1:54 | comment | added | 640KB |
@PeterCordes good point! I've reverted that part of the change so it once again returns to uint64_t *out_ds_bx . Thanks!
|
|
Jan 26, 2020 at 1:53 | history | edited | 640KB | CC BY-SA 4.0 |
i/o fix
|
Jan 26, 2020 at 1:48 | comment | added | Peter Cordes |
i.e. void halfshift(uint64_t *out_ds_bx, long double in_st0); would be a valid and legal custom calling convention.
|
|
Jan 26, 2020 at 1:47 | history | rollback | 640KB |
Rollback to Revision 6
|
|
Jan 26, 2020 at 1:44 | comment | added | Peter Cordes |
Oh wait, this relies on the caller to do the rounding to nearest integer. That's not allowed. We need frndint , or fistp to an output pointer. Input can still be an integer FP value in ST0 though.
|
|
Jan 26, 2020 at 1:39 | history | edited | 640KB | CC BY-SA 4.0 |
-4 bytes, use FPU register for I/O
|
Jan 26, 2020 at 1:32 | comment | added | 640KB |
@PeterCordes, sure that would make sense to just do i/o using ST0 (especially since the stated platform is "8087 FPU"). Would cut 4 bytes and possibly increase the highest number of N by a little bit too (at least until the result is lte than \$2^{63}-1\$, whatever that is). Also the opcode DE F9 (FDIV ) is actually FDIVP ST(1), ST so that's already good there.
|
|
Jan 25, 2020 at 19:17 | comment | added | Peter Cordes |
Or for this integer-by-reference convention, use fidvr . Oh, but there's no m64int form of that, only 16 and 32! So that only works for int32_t . Now I see why you had to use fild to handle a qword integer. I don't think we can beat that with SSE2 in 64-bit mode; divsd is at least 4 bytes, and if you need an addressing mode it's more.
|
|
Jan 25, 2020 at 19:10 | comment | added | Peter Cordes |
heh, x87 has a bunch of constants build in, including pi and log and ln(2), and log2() of e and 10, but not sqrt 2. :/ push 2 / fild wouldn't help either. Suggestion: custom calling convention: input in ST0, return in ST0. Then you just use fdivp after setting up the constant.
|
|
Jan 24, 2020 at 22:37 | history | edited | 640KB | CC BY-SA 4.0 |
added 396 characters in body
|
Jan 24, 2020 at 22:07 | history | edited | 640KB | CC BY-SA 4.0 |
64-bit QWORD instead of 16-bit WORD
|
Jan 24, 2020 at 19:41 | history | edited | 640KB | CC BY-SA 4.0 |
added 43 characters in body
|
Jan 24, 2020 at 19:19 | history | edited | 640KB | CC BY-SA 4.0 |
deleted 132 characters in body
|
Jan 24, 2020 at 19:08 | history | edited | 640KB | CC BY-SA 4.0 |
added 28 characters in body
|
Jan 24, 2020 at 19:01 | history | answered | 640KB | CC BY-SA 4.0 |