#!/bin/bash

in=$1

# Get the input argument
if [ "$#" -eq  "0" ]; then
    echo "No arguments supplied"
    echo "Usage: llvm-to-elf input.ll [output.elf]"
    exit 1
fi

# Get the optional output elf file name
if [ -z "$2" ]; then
    out="$1.elf"
    echo "Output file: $out"
else
    out="$2"
fi


set -e

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
ROOT="$DIR/.."
TOOLCHAIN_DIR=$(realpath "$ROOT/toolchains/riscv32")

OPT="-O1"
CFLAGS="\
    --target=riscv32 \
    -mabi=ilp32d \
    -march=rv32gc \
    -mcmodel=medium \
    -I$TOOLCHAIN_DIR \
    -I$TOOLCHAIN_DIR/lib/include \
    -fno-common \
    -ffunction-sections \
    -fdata-sections"


LDFLAGS="\
    --target=riscv32 \
    -mabi=ilp32d \
    -march=rv32gc \
    -fuse-ld=lld \
    -nostartfiles \
    -nodefaultlibs \
    -nostdlib \
    -static \
    -T$TOOLCHAIN_DIR/linkerscript.ld \
    -L$TOOLCHAIN_DIR \
    -L$TOOLCHAIN_DIR/lib/gcc \
    -L$TOOLCHAIN_DIR/lib/libc \
    -Wl,--gc-sections \
    -Wl,--Bstatic \
    -Wl,-lgcc"

# Compile the .ll file
#llc -filetype=obj $OPT -O=1 -o $in.obj $in
clang -c $OPT $CFLAGS $in -o $in.obj

# Compile crt.S
#clang -c -O1 $CFLAGS $TOOLCHAIN_DIR/crt.S -o crt.obj
#
## Compile syscalls.c
#clang -c -O1 $CFLAGS $TOOLCHAIN_DIR/syscalls.c -o syscalls.obj
#
## Compile printf.c
#clang -c -O1 $CFLAGS $TOOLCHAIN_DIR/printf.c -o printf.obj
#
## Compile cache_hint.c
#clang -c -O1 $CFLAGS $TOOLCHAIN_DIR/cache_hint.c -o cache_hint.obj

# Link
clang $LDFLAGS $in.obj -Wl,-Map=$in.map crt.obj cache_hint.obj syscalls.obj printf.obj -o $out

# Disassemble
llvm-objdump -d $out > $in.s

# Cleanup
rm -rf $in.obj syscalls.obj cache_hint.obj printf.obj
