Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 840871
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T05:41:55+00:00 2026-05-15T05:41:55+00:00

I am facing a rather peculiar problem. I am working on a compiler for

  • 0

I am facing a rather peculiar problem. I am working on a compiler for an architecture that doesn’t support bitwise operations. However, it handles signed 16-bit integer arithmetics and I was wondering if it would be possible to implement bitwise operations using only:

  • Addition (c = a + b)
  • Subtraction (c = a – b)
  • Division (c = a / b)
  • Multiplication (c = a * b)
  • Modulus (c = a % b)
  • Minimum (c = min(a, b))
  • Maximum (c = max(a, b))
  • Comparisons (c = (a < b), c = (a == b), c = (a <= b), et.c.)
  • Jumps (goto, for, et.c.)

The bitwise operations I want to be able to support are:

  • Or (c = a | b)
  • And (c = a & b)
  • Xor (c = a ^ b)
  • Left Shift (c = a << b)
  • Right Shift (c = a >> b)
  • (All integers are signed so this is a problem)
  • Signed Shift (c = a >>> b)
  • One’s Complement (a = ~b)
  • (Already found a solution, see below)

Normally the problem is the other way around; how to achieve arithmetic optimizations using bitwise hacks. However not in this case.

Writable memory is very scarce on this architecture, hence the need for bitwise operations. The bitwise functions themselves should not use a lot of temporary variables. However, constant read-only data & instruction memory is abundant. A side note here also is that jumps and branches are not expensive and all data is readily cached. Jumps cost half the cycles as arithmetic (including load/store) instructions do. On other words, all of the above supported functions cost twice the cycles of a single jump.


Some thoughts that might help:

I figured out that you can do one’s complement (negate bits) with the following code:

// Bitwise one's complement
b = ~a;
// Arithmetic one's complement
b = -1 - a;

I also remember the old shift hack when dividing with a power of two so the bitwise shift can be expressed as:

// Bitwise left shift
b = a << 4;
// Arithmetic left shift
b = a * 16; // 2^4 = 16

// Signed right shift
b = a >>> 4;
// Arithmetic right shift
b = a / 16;

For the rest of the bitwise operations I am slightly clueless. I wish the architects of this architecture would have supplied bit-operations.

I would also like to know if there is a fast/easy way of computing the power of two (for shift operations) without using a memory data table. A naive solution would be to jump into a field of multiplications:

b = 1;
switch (a)
{
  case 15: b = b * 2;
  case 14: b = b * 2;
  // ... exploting fallthrough (instruction memory is magnitudes larger)
  case 2: b = b * 2;
  case 1: b = b * 2;
}

Or a Set & Jump approach:

switch (a)
{
  case 15: b = 32768; break;
  case 14: b = 16384; break;
  // ... exploiting the fact that a jump is faster than one additional mul
  //     at the cost of doubling the instruction memory footprint.
  case 2: b = 4; break;
  case 1: b = 2; break;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T05:41:55+00:00Added an answer on May 15, 2026 at 5:41 am

    First solutions for shifting (shift is the shift distance, must not be negative, a is the operand to be shifted and contains also the result when done). The power table is used by all three shift operations.

    // table used for shift operations
    powtab = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, -32768 };
    
    // logical shift left
    if (shift > 15) {
         a = 0; // if shifting more than 15 bits to the left, value is always zero
    } else {
         a *= powtab[shift];
    }
    
    // logical shift right (unsigned)
    if (shift > 15) {
        a = 0; // more than 15, becomes zero
    } else if (shift > 0) {
        if (a < 0) {
            // deal with the sign bit (15)
            a += -32768;
            a /= powtab[shift];
            a += powtab[15 - shift];
        } else {
            a /= powtab[shift];
        }
    }
    
    // arithmetic shift right (signed)
    if (shift >= 15) {
        if (a < 0) {
            a = -1;
        } else {
            a = 0;
        }
    } else if (shift > 0) {
        if (a < 0) {
            // deal with the sign bit
            a += -32768;
            a /= powtab[shift];
            a -= powtab[15 - shift];
        } else {
            // same as unsigned shift
            a /= powtab[shift];
        }
    }
    

    For AND, OR and XOR i could not come up with a simple solution, so i’ll do it with looping over each single bit. There might be a better trick to do this. Pseudocode assumes a and b are input operands, c is the result value, x is the loop counter (each loop must run exactly 16 times):

    // XOR (^)
    c = 0;
    for (x = 0; x <= 15; ++x) {
        c += c;
        if (a < 0) {
            if (b >= 0) {
                c += 1;
            }
        } else if (b < 0) {
            c += 1;
        }
        a += a;
        b += b;
    }
    
    // AND (&)
    c = 0;
    for (x = 0; x <= 15; ++x) {
        c += c;
        if (a < 0) {
            if (b < 0) {
                c += 1;
            }
        }
        a += a;
        b += b;
    }
    
    // OR (|)
    c = 0;
    for (x = 0; x <= 15; ++x) {
        c += c;
        if (a < 0) {
            c += 1;
        } else if (b < 0) {
            c += 1;
        }
        a += a;
        b += b;
    }
    

    Thats assuming that all variables are 16 bits and all operations behave as signed (so a<0 actually is true when bit 15 is set).

    EDIT: i actually tested all possible operand values (-32768 to 32767) for shifts ranging from 0 to 31 for correctness and it works correctly (assuming integer divides). For the AND/OR/XOR code an exhaustive test takes too long on my machine, but since the code for these is pretty simple there should be no edge cases anyway.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.