Skip to main content

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