Q:

16bit*32bit MUL with 48bit result

I want to do 16bit * 32bit Mul operation but using only 32bit register.  Result can be caught by two 32 bit registers as output is 48bits. 
I want C code for this problem! 
I have 32bit*32bit MUL with 64bit output function but i can not use this function here properly because of signs.  For exapmle 16bit minus one is 0xFFFF and 32bit minus one is 0xFFFFFFFF. 
I will be using this code for LLVM translation of MUL. 

A:

Are you trying to do something like this? 
#include <inttypes.h>

void multiply(uint16_t*top,uint32_t*bottom, uint16_t lhs,uint32_t rhs){

    uint32_t low=lhs*(rhs&0xFFFF);
    uint32_t high=lhs*(rhs>>16)+(low>>16);
    *bottom=(high)<<16)|(low&0xFFFF);
    *top=(high>>16);
}

It's a whole lot easier when you realize you're multiplying a single digit number by a two digit number all in base 65536 (2**16). 
I've only used 64-bit to check and display the output. 
The multiply operates in 32-bit. 
Here it is in test harness:
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

void multiply(uint16_t*top,uint32_t*bottom, uint16_t lhs,uint32_t rhs){

    uint32_t low=lhs*(rhs&0xFFFF);
    uint32_t high=lhs*(rhs>>16)+(low>>16);
    *bottom=(high)<<16)|(low&0xFFFF);
    *top=(high>>16);
}

uint64_t encode64(uint16_t top,uint32_t bottom){
    return (((uint64_t)top)<<32)|((uint64_t)bottom);
}

int check(uint16_t lhs,uint32_t rhs){
    uint16_t t16;
    uint32_t t32;

    multiply(&t16,&t32,lhs,rhs);
    const uint64_t result=encode64(t16,t32);

    uint64_t llhs=lhs;
    uint64_t lrhs=rhs;
    uint64_t expect=llhs*lrhs;

    if(result==expect){
        return 0;
    }
    printf("%"PRIu16"*%"PRIu32"==%"PRIu64"!=%"PRIu64"\n",lhs,rhs,result,expect);
    return 1;
}

int main(void) {
    int error=0;
    uint16_t top;
    uint32_t bottom;
    uint16_t lhs=58989;
    uint32_t rhs=5978342;
    error+=check(2U,20UL);
    error+=check(0xFFFF,0xFFFFFFFF);
    error+=check(768U,565354767UL);
    error+=check(26434U,566534767UL);
    error+=check(26434U,690789UL);
    error+=check(5678U,9767889UL);
    error+=check(3674U,784367UL);
    error+=check(0,690789ULL);
    error+=check(0,0xFFFFFFFF);
    error+=check(0xFFFF,0);
    error+=check(0xFFFF,1);
    error+=check(1,0xFFFFFFFF);
    error+=check(0x2,0xAFFFFFFF);       
    multiply(&top,&bottom,lhs,rhs);

    uint64_t result=encode64(top,bottom);

    printf("%"PRIu16"*%"PRIu32"==%"PRIu64"\n",lhs,rhs,result);

    if(error!=0){
        printf("\nErrors=%d\n",error);
    }

    return error==0?EXIT_SUCCESS:EXIT_FAILURE;
}

