TechnoCave778
TechnoCave778

Reputation: 11

ppc EXTDRI instruction equivalent in C++

Could someone show me an example in C++ of what this PowerPC instruction would look like?

From what I get, we are looking 44 bits shifted to the right inside of r0, and from there we are extracting the first 8 bits

extrdi    r0, r0, 8,44

Upvotes: 1

Views: 296

Answers (2)

Qiu Chaofan
Qiu Chaofan

Reputation: 135

According to PowerPC mnemonics document, extrdi means extract n bits since bit b, then right-justify it.

Take an 8-bit integer to illustrate:

extrdi r0, r0, 2, 3

r0: A B C D E F G H
        |   |
        +---+
        2 2+3-1

After extraction:    0 0 C D E 0 0 0
After justification: 0 0 0 0 0 C D E

We can implement as below (64-bit):

unsigned long extrdi_soft(unsigned long ry, unsigned n, unsigned b) {
  unsigned offset = (64 - b - n);
  // Generate the n-bit mask beginning from position b
  unsigned mask = ((1UL << n) - 1) << offset;
  // Do mask and right-justify it
  return (ry & mask) >> offset;
}

Compare it against real extrdi:

unsigned long extrdi_hard(unsigned long rs) {
  unsigned long ra = 0;
  asm("extrdi %1, %0, 8, 44"
     :"=r"(ra)
     :"r"(rs));
  return ra;
}

// extrdi_hard(0x1234567UL) == extrdi_soft(0x1234567UL, 8, 44)

extrdi rs, ry, n, b is actually mnemonic to rldicl rs, ry, b+n, 64-n. The instruction means rotate left then clear left. So we got another way to implement extrdi:

unsigned long rotl64(unsigned long rs, unsigned n) {
  return (rs << n) | (rs >> (64-n));
}

unsigned long rldicl(unsigned long rs, unsigned sh, unsigned mb) {
  return rotl64(rs, sh) & ((1UL << (64 - mb)) - 1);
}

unsigned long extrdi(unsigned long ry, unsigned n, unsigned b) {
  return rldicl(ry, b+n, 64-n);
}

Upvotes: 1

dja
dja

Reputation: 1503

The ISA says extrdi is 'Extract and right justify immediate', and it's an extended mnemonic for rldicl ('Rotate left double-word immediate and clear left') - v2.07 pg 717. So your statement is equivalent to rldicl r0, r0, 52, 56.

So, you want to extract 8 bits starting at position 44, and then right justify it, which would make it the least-significant 8 bits. It's worth noting that IBM bit numbers go the opposite way to what you'd probably expect: conventional bit = 63 - IBM bit. So IBM bits 44 to 51 are 'conventional' bit number 12 to 19.

We simply shift down so that bit 12 becomes bit 0 and bit 19 becomes bit 7 - a shift of 12 places. We then need to mask it so we only get the least-significant 8 bits.

unsigned long extrdi(unsigned long a) {
  return (a >> 12) & 0xff;
}

Looking on godbolt.org: https://godbolt.org/z/rGe3EW, we see this is indeed:

extrdi:
        rldicl 3,3,52,56
        blr
        .long 0
        .byte 0,0,0,0,0,0,0,0

(r3 is the argument and return register)

Upvotes: 4

Related Questions