Example #1
0
        /// <summary>
        /// CompileWithoutSpecs is used in conjunction with CompileForBin. Its primary use is to get 
        /// the number of registers and size needs of the asm block.
        /// </summary>
        public void CompileForSpecs(string[] srcLines, out List<Stmt> _gcnStmts, out List<RegUsage> sRegUsage,
            out List<RegUsage> vRegUsage, out int binSize, out string logOutput)
        {
            Log log = new Log();
            vars = new Variables(UseRegPool: false, CalcRegUsage: true, log: log);

            Compile(srcLines, out binSize, log);
            _gcnStmts = gcnStmts;

            sRegUsage = vars.sRegUsageCalc.GetUsage();
            vRegUsage = vars.vRegUsageCalc.GetUsage();
            logOutput = log.ToString();
        }
Example #2
0
        /// <summary>
        /// CompileForBin takes an asm block and creates a bin. #s_pool and #v_pool can optionally 
        /// be used to specify what register numbers are available.
        /// </summary>
        public byte[] CompileForBin(string[] srcLines, out List<Stmt> _gcnStmts, out int binSize,
            out string logOutput, out bool compileSuccessful)
        {
            Log log = new Log();
            // only initialize s and vRegPool here if we are creating a bin
            vars = new Variables(UseRegPool: true, CalcRegUsage: false, log: log);

            byte[] bin = Compile(srcLines, out binSize, log);
            _gcnStmts = gcnStmts;

            logOutput = log.ToString();
            compileSuccessful = !log.hasErrors;
            return bin;
        }
Example #3
0
        public int ISA_Gen = 2; //default to 2;


        /// <summary>
        /// Compiles for both specifications and binary output. 
        /// </summary>
        public byte[] CompileFull(string[] srcLines, out List<Stmt> _gcnStmts, out List<RegUsage> sRegUsage,
            out List<RegUsage> vRegUsage, out int binSize, out string logOutput, out bool compileSuccessful)
        {
            Log log = new Log();
            vars = new Variables(UseRegPool: true, CalcRegUsage: true, log: log);

            byte[] bin = Compile(srcLines, out binSize, log);

            _gcnStmts = gcnStmts;

            sRegUsage = vars.sRegUsageCalc.GetUsage();
            vRegUsage = vars.vRegUsageCalc.GetUsage();
            logOutput = log.ToString();
            compileSuccessful = !log.hasErrors;
            return bin;
        }
Example #4
0
 public static void DecodeVal(string stmtText, string src0Name, ref char src0Type, ref char src0Scaler, ref int src0Size, Variables vars, Log log)
 {
     char firstChar = src0Name[0];
     int junk;
     if (vars.varsByName.ContainsKey(src0Name))
     {
         Variable v = vars.varsByName[src0Name];
         src0Scaler = v.isScaler ? 's' : 'v';
         src0Size = v.size;
         src0Type = v.type;
     }
     else if (firstChar == 's' | firstChar == 'v' &&
         int.TryParse(src0Name.Substring(1), out junk))
     {
         src0Scaler = firstChar;
     }
     else if ((firstChar >= '0' && firstChar <= '9') || firstChar == '-')
     {
         src0Scaler = 'c';
         src0Size = 0;
         int temp;
         if (int.TryParse(src0Name, out temp))
         {
             src0Type = 'b';
             if (temp >= -16 && temp <= 64)
                 src0Size = 1;
             else if ((temp & 0xFFFF0000) == 0)
                 src0Size = 2;
             else
                 src0Size = 4;
         }
         else if (src0Name == "-0.5" || src0Name == "0.5" || src0Name == "-1.0" || src0Name == "1.0" || src0Name == "-2.0" || src0Name == "2.0" || src0Name == "-4.0" || src0Name == "4.0")
         {
             src0Size = 1;
             src0Type = 'f';
         }
         else
             log.Error("Unable to decode '{0}' in '{1}'.", src0Name, stmtText);
     }
     else
     {
         log.Error("Unable to find the source data-type of '{0}'.", stmtText);
     }
 }
Example #5
0
        public static string FriendlyFormatToAsmFormater(string stmtText, Variables vars, int ISA_Gen, Log log)
        {
            // find: v4u d = a + b ---> v_add_i32  v4u d, vcc, a, b 
            Match m = Regex.Match(stmtText,
                @"(?<![a-z_0-9])(?<1>(?<2>s|v)(?<3>1|2|4|8|16)(?<4>[fiub])[ \t]+)?(?<5>[A-Za-z_0-9\.]+)[ \t]*=[ \t]*(?<6>[A-Za-z_0-9\.]*)" +
                @"[ \t]*(?<7>\+|\*|\-|\>\>|\<\<)" +
                @"[ \t]*(?<8>[A-Za-z_0-9\.]*)");

            if (!m.Success)
                return stmtText;

            char opp = m.Groups[7].Value[0];
            string destName = m.Groups[5].Value, src0Name = m.Groups[6].Value, src1Name = m.Groups[8].Value;
            char destType = 'b', src0Type = 'b', src1Type = 'b';
            char destScaler = '_', src0Scaler = '_', src1Scaler = '_';
            int destSize = 0, src0Size = 0, src1Size = 0; // 0 = unknown
            bool hasDecloration = m.Groups[1].Success;
            string declorationType = "";
            int junk;

            // Lets figure out the destination type
            if (hasDecloration)
            {
                destScaler = m.Groups[2].Value[0];
                destSize = int.Parse(m.Groups[3].Value);
                destType = m.Groups[4].Value[0];
                declorationType = m.Groups[1].Value + " ";
            }
            else if (vars.varsByName.ContainsKey(destName))
            {
                Variable v = vars.varsByName[destName];
                destScaler = v.isScaler ? 's' : 'v';
                destSize = v.size;
                destType = v.type;
            }
            else if (destName[0] == 's' | destName[1] == 'v' &&
                int.TryParse(destName.Substring(1), out junk))
            {
                destScaler = destName[0];
            }
            else
            {
                log.Error("Unable to find the destination data-type of '{0}'.", stmtText);
                return "";
            }


            // Lets figure out the source0 and source1 types
            DecodeVal(stmtText, src0Name, ref src0Type, ref src0Scaler, ref src0Size, vars, log);
            DecodeVal(stmtText, src1Name, ref src1Type, ref src1Scaler, ref src1Size, vars, log);
            
            if (src0Type == 'c' && src1Type == 'c')
            {
                log.Error("Both sources cannot be constants. '{0}'", stmtText);
                return "";
            }
            
            if (opp == '+')
            {
                if (destScaler == 's')
                {
                    if (destSize != 4)
                    {
                        log.Error("Scalar destination size must be 4 bytes. '{0}'", stmtText);
                        return "";
                    }

                    if (!((src0Size == 4) || (src0Size == 0)
                        || (src1Size == 4) || (src1Size == 0)))
                    {
                        log.Error("Scalar source size must be 4. '{0}'", stmtText);
                        return "";
                    }

                    if (destType == 'i')
                    { // s4i = ??? + ???
                        if (src0Type != 'c' && src1Type != 'c')
                            return "s_add_i32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else if (src0Type == 'c' && src0Size == 2)
                            return "s_addk_i32 " + declorationType + destName + ", " + src1Name + ", " + src0Name;
                        else if (src0Type == 'c') //for sizes -16-64 or larger then 16-bit use normal add
                            return "s_add_i32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("Error decoding friendly format for '{0}'.", stmtText);
                            return "";
                        }
                    }
                    else if (destType == 'u' || destType == 'b')
                    { // s4u = ??? + ???
                        if (src0Type != 'c' && src1Type != 'c')
                            return "s_add_u32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else if (src0Type == 'c' && src0Size == 2)
                            return "s_addk_i32 " + declorationType + destName + ", " + src1Name + ", " + src0Name;
                        else if (src0Type == 'c') //for sizes -16-64 or larger then 16-bit use normal add
                            return "s_add_u32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("Error decoding friendly format for '{0}'.", stmtText);
                            return "";
                        }
                    }
                    else if (destType == 'f')
                    {
                        log.Error("Scalar destinations of type float are not supported. '{0}'", stmtText);
                        return "";
                    }
                    else
                    {
                        log.Error("Unknown error when processing: '{0}'", stmtText);
                        return "";
                    }
                }
                else // is vector
                {
                    if (!((destSize == 2) || (destSize == 4) || (destSize == 8) || (destSize == 0)))
                    {
                        log.Error("Vector destination size must be 2, 4, or 8 bytes. '{0}'", stmtText);
                        return "";
                    }

                    if (!((src0Size == 2) || (src0Size == 4) || (src0Size == 8) || (src0Size == 0)
                        || (src1Size == 2) || (src1Size == 4) || (src1Size == 8) || (src1Size == 0)))
                    {
                        log.Error("Vector source size must be 2, 4, or 8 bytes. '{0}'", stmtText);
                        return "";
                    }

                    if (destSize == 2)
                    {
                        if (destType == 'i') // v2i = ??? + ???
                            return "v_add_i16 " + declorationType + destName + "," + src0Name + "," + src1Name;
                        else if (destType == 'u' || destType == 'b') // v2u = ??? + ???
                            return (ISA_Gen == 2 ? "v_add_i16 " : "v_add_u16 ") + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        //return "v_add_u16 " + destName + "," + src0Name + "," + src1Name;
                        else if (destType == 'f') // v2f = ??? + ???
                            return "v_add_f16 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("Vector destination type not supported. '{0}'", stmtText);
                            return "";
                        }
                    }
                    else if (destSize == 4)
                    {
                        if (destType == 'i')
                            return "v_add_i32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else if (destType == 'u' || destType == 'b')
                            return (ISA_Gen == 2 ? "v_add_i32 " : "v_add_u32 ") + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else if (destType == 'f')
                            return "v_add_f32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("Vector destination type not supported. '{0}'", stmtText);
                            return "";
                        }
                    }
                    else if (destSize == 8)
                    {
                        if (destType == 'f')
                            return "v_add_f64 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("64-bit add operations are not supported. '{0}'", stmtText);
                            return "";
                        }
                    }
                }
            }
            else if (opp == '-')
            {
                if (destScaler == 's')
                {
                    if (destSize != 4)
                    {
                        log.Error("Scalar destination size must be 4 bytes. '{0}'", stmtText);
                        return "";
                    }

                    if (!((src0Size == 4) || (src0Size == 0)
                        || (src1Size == 4) || (src1Size == 0)))
                    {
                        log.Error("Scalar source size must be 4. '{0}'", stmtText);
                        return "";
                    }

                    if (destType == 'i')
                    { // s4i = ??? + ???
                        return "s_sub_i32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                    }
                    else if (destType == 'u' || destType == 'b')
                    { // s4u = ??? + ???
                        return "s_sub_u32 " + declorationType + destName + ", " + src0Name + ", " + src1Name; 
                    }
                    else if (destType == 'f')
                    {
                        log.Error("Scalar destinations of type float are not supported. '{0}'", stmtText);
                        return "";
                    }
                    else
                    {
                        log.Error("Unknown error when processing: '{0}'", stmtText);
                        return "";
                    }
                }
                else // is vector
                {
                    if (!((destSize == 2) || (destSize == 4) || (destSize == 8) || (destSize == 0)))
                    {
                        log.Error("Vector destination size must be 2, 4, or 8 bytes. '{0}'", stmtText);
                        return "";
                    }

                    if (!((src0Size == 2) || (src0Size == 4) || (src0Size == 8) || (src0Size == 0)
                        || (src1Size == 2) || (src1Size == 4) || (src1Size == 8) || (src1Size == 0)))
                    {
                        log.Error("Vector source size must be 2, 4, or 8 bytes. '{0}'", stmtText);
                        return "";
                    }

                    if (destSize == 2)
                    {
                        if (destType == 'i') // v2i = ??? - ???
                            return "v_sub_i16 " + declorationType + destName + "," + src0Name + "," + src1Name;
                        else if (destType == 'u' || destType == 'b') // v2u = ??? + ???
                            return (ISA_Gen == 2 ? "v_sub_i16 " : "v_sub_u16 ") + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        //return "v_add_u16 " + destName + "," + src0Name + "," + src1Name;
                        else if (destType == 'f') // v2f = ??? - ???
                            return "v_sub_f16 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("Vector destination type not supported. '{0}'", stmtText);
                            return "";
                        }
                    }
                    else if (destSize == 4)
                    {
                        if (destType == 'i')
                            return "v_sub_i32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else if (destType == 'u' || destType == 'b')
                            return (ISA_Gen == 2 ? "v_sub_i32 " : "v_sub_u32 ") + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else if (destType == 'f')
                            return "v_sub_f32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("Vector destination type not supported. '{0}'", stmtText);
                            return "";
                        }
                    }
                    else if (destSize == 8)
                    {
                        log.Error("64-bit vector subtract operations not supported. '{0}'", stmtText);
                        return "";
                    }
                }
            }
            else if (opp == '*')
            {
                if (destScaler == 's')
                {
                    if (destSize != 4)
                    {
                        log.Error("Scalar destination size must be 4 bytes. '{0}'", stmtText);
                        return "";
                    }

                    if (destType == 'f')
                    {
                        log.Error("Scalar destinations of type float are not supported for multiply. '{0}'", stmtText);
                        return "";
                    }

                    if (src0Type != 'c' && src1Type != 'c')
                        return "s_mul_i32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                    else if (src0Type == 'c' && src0Size == 2)
                        return "s_mulk_i32 " + declorationType + destName + ", " + src1Name + ", " + src0Name;
                    else if (src0Type == 'c') //for +/- 0.5 1.0 2.0 4.0  use normal multiply
                        return "s_mul_i32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                    else
                    {
                        log.Error("Error decoding friendly format for '{0}'.", stmtText);
                        return "";
                    }
                }
                else // is vector
                {
                    if (destSize == 2)
                    {
                        if (destType == 'f')
                            return "v_mul_f16 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("With a 16-bit vector destination, only floats are supported. '{0}'", stmtText);
                            return "";
                        }
                    }
                    else if (destSize == 4)
                    {
                        if (destType == 'i')
                            return "v_mul_i32_i24 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else if (destType == 'u' || destType == 'b')
                            return "v_mul_u32_u24 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else if (destType == 'f')
                            return "v_mul_f32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("Vector destination type not supported. '{0}'", stmtText);
                            return "";
                        }
                    }
                    else if (destSize == 8)
                    {
                        if (destType == 'f')
                            return "v_mul_f32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else
                        {
                            log.Error("Vector destination type not supported. '{0}'", stmtText);
                            return "";
                        }
                    }
                }
            }
            else if (opp == '>')
            {
                if (destScaler == 's')
                {
                    if (destSize == 4)
                    {
                        if (destType == 'i')    // s4i = ??? >> ???
                            return "s_lshr_i32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else                    // s4u = ??? >> ???
                            return "s_lshr_b32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                    }
                    else if (destSize == 8)
                    {
                        if (destType == 'i')    // s8i = ??? >> ???
                            return "s_lshr_i64 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                        else                    // s8u = ??? >> ???
                            return "s_lshr_b64 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                    }
                    else
                    {
                        log.Error("The destination size is not supported. '{0}'", stmtText);
                        return "";
                    }
                }
                else // is vector
                {
                    if (destSize == 2)
                    { 
                        if (destType == 'i') // v2i = ??? >> ???
                            return "v_ashrrev_i16 " + declorationType + destName + "," + src1Name + "," + src0Name;
                        else 
                            return "v_lshrrev_b16 " + declorationType + destName + ", " + src1Name + "," + src0Name;
                    }
                    else if (destSize == 4)
                    {
                        if (destType == 'i') // v4i = ??? >> ???
                            return "v_ashrrev_i32 " + declorationType + destName + ", " + src1Name + "," + src0Name;
                        else
                            return "v_lshrrev_b32 " + declorationType + destName + ", " + src1Name + "," + src0Name;
                    }
                    else if (destSize == 8)
                    {
                        if (destType == 'i') // v4i = ??? >> ???
                            return "v_ashrrev_i64 " + declorationType + destName + ", " + src1Name + "," + src0Name;
                        else
                            return "v_lshrrev_b64" + declorationType + destName + ", " + src1Name + "," + src0Name;
                    }
                    else
                    {
                        log.Error("The destination size is not supported. '{0}'", stmtText);
                        return "";
                    }
                }
            }
            else if (opp == '<') // for '<<'
            {
                if (destScaler == 's')
                {
                    if (destSize == 4)
                        return "s_lshl_b32 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                    else if (destSize == 8)
                       return "s_lshl_i64 " + declorationType + destName + ", " + src0Name + ", " + src1Name;
                    else
                    {
                        log.Error("The destination size is not supported. '{0}'", stmtText);
                        return "";
                    }
                }
                else // is vector
                {
                    if (destSize == 2)
                        return "v_lshlrev_b16 " + declorationType + destName + ", " + src1Name + "," + src0Name;
                    else if (destSize == 4)
                        return "v_lshlrev_b32 " + declorationType + destName + ", " + src1Name + "," + src0Name;
                    else if (destSize == 8)
                        return "v_lshlrev_b64 " + declorationType + destName + ", " + src1Name + "," + src0Name;
                    else
                    {
                        log.Error("The destination size is not supported. '{0}'", stmtText);
                        return "";
                    }
                }
            }
            else
            {
                log.Error("Friendly conversion not recognized. '{0}'", stmtText);
                return "";
            }

            return "";
        }