Exemplo n.º 1
0
 def compile_and_link(self, src, dst):
     """Compile and link a file directly."""
     cmd = [self.get_command(), src, "-o", dst] + self.__standard + self.__compiler_flags + self._compiler_flags_extra + self._definitions + \
         self._include_directories + self.get_linker_flags() + self.get_library_directory_list() + self.get_library_list()
     (so, se) = run_command(cmd)
     if 0 < len(se) and is_verbose():
         print(se)
Exemplo n.º 2
0
 def compile_asm(self, src, dst, whole_program=False):
     """Compile a file into assembler source."""
     cmd = [self.get_command(), "-S", src, "-o", dst] + self.__standard + self.__compiler_flags + \
         self._compiler_flags_extra + self._definitions + self._include_directories
     if whole_program:
         cmd += self.__compiler_flags_whole_program
     (so, se) = run_command(cmd)
     if 0 < len(se) and is_verbose():
         print(se)
Exemplo n.º 3
0
 def crunch_entry_push(self, op):
     """Crunch amd64/ia32 push directives from given line listing."""
     lst = self.want_label(op)
     if not lst:
         return
     ii = lst[0] + 1
     jj = ii
     stack_decrement = 0
     stack_save_decrement = 0
     reinstated_lines = []
     while True:
         current_line = self.__content[jj]
         match = re.match(r'\s*(push\w).*%(\w+)', current_line,
                          re.IGNORECASE)
         if match:
             if is_stack_save_register(match.group(2)):
                 stack_save_decrement += get_push_size(match.group(1))
             else:
                 stack_decrement += get_push_size(match.group(1))
             jj += 1
             continue
         # Preserve comment lines as they are.
         match = re.match(r'^\s*[#;].*', current_line, re.IGNORECASE)
         if match:
             reinstated_lines += [current_line]
             jj += 1
             continue
         # Saving stack pointer or sometimes initializing edx seem to be within pushing.
         match = re.match(r'\s*mov\w\s+%\w+,\s*%(rbp|ebp|edx).*',
                          current_line, re.IGNORECASE)
         if match:
             if is_stack_save_register(match.group(1)):
                 stack_save_decrement = 0
             reinstated_lines += [current_line]
             jj += 1
             continue
         # Some types of lines can be in the middle of pushing.
         if is_reinstate_line(current_line):
             reinstated_lines += [current_line]
             jj += 1
             continue
         match = re.match(r'\s*sub.*\s+[^\d]*(\d+),\s*%(rsp|esp)',
                          current_line, re.IGNORECASE)
         if match:
             total_decrement = int(
                 match.group(1)) + stack_decrement + stack_save_decrement
             self.__content[jj] = re.sub(r'\d+', str(total_decrement),
                                         current_line)
         break
     if is_verbose():
         print("Erasing function header from '%s': %i lines" %
               (op, jj - ii - len(reinstated_lines)))
     self.erase(ii, jj)
     self.__content[ii:ii] = reinstated_lines
Exemplo n.º 4
0
 def write(self):
     """Write compressed output."""
     fd = open(self.__output_name, "w")
     if not fd:
         raise RuntimeError("could not write GLSL header '%s'" %
                            (self.__output_name))
     fd.write(self.generateHeaderOutput())
     fd.close()
     if is_verbose():
         print("Wrote GLSL header: '%s' => '%s'" %
               (self.__variable_name, self.__output_name))
Exemplo n.º 5
0
 def format(self, force):
     """Return formatted output."""
     ret = "."
     if self.__swizzle:
         if not self.__swizzle_export:
             if force:
                 if is_verbose():
                     print("WARNING: %s swizzle status unconfirmed" %
                           (str(self)))
                 return ret + self.__name.format(force)
             return ""
         return ret + self.generateSwizzle()
     return ret + self.__name.format(force)
Exemplo n.º 6
0
 def __init__(self, lst, explicit):
     """Constructor."""
     GlslBlock.__init__(self)
     self.__explicit = explicit
     self.__squashable = False
     self.__allow_squash = False
     # Check for degenerate scope.
     if (1 == len(lst)) and is_glsl_block_declaration(lst[0]):
         raise RuntimeError("scope with only block '%s' is degenerate" %
                            (lst[0].format(True)))
     # Check for empty scope (likely an error).
     if 0 >= len(lst):
         if is_verbose():
             print("WARNING: empty scope")
     # Hierarchy.
     self.addChildren(lst)
Exemplo n.º 7
0
 def crunch_jump_pop(self, op):
     """Crunch popping before a jump."""
     lst = self.want_line(r'\s*(jmp\s+%s)\s+.*' % (op))
     if not lst:
         return
     ii = lst[0]
     jj = ii - 1
     while True:
         if (0 > jj) or not re.match(r'\s*(pop\S).*', self.__content[jj],
                                     re.IGNORECASE):
             if is_verbose():
                 print(
                     "Erasing function footer before jump to '%s': %i lines"
                     % (op, ii - jj - 1))
             self.erase(jj + 1, ii)
             break
         jj -= 1
Exemplo n.º 8
0
 def crunch_amd64(self, lst):
     """Perform platform-dependent crunching."""
     self.crunch_entry_push("_start")
     self.crunch_entry_push(ELFLING_UNCOMPRESSED)
     self.crunch_jump_pop(ELFLING_UNCOMPRESSED)
     lst = self.want_line(r'\s*(int\s+\$0x3|syscall)\s+.*')
     if lst:
         ii = lst[0] + 1
         jj = ii
         while True:
             if len(self.__content) <= jj or re.match(
                     r'\s*\S+\:\s*', self.__content[jj]):
                 if is_verbose():
                     print("Erasing function footer after '%s': %i lines" %
                           (lst[1], jj - ii))
                 self.erase(ii, jj)
                 break
             jj += 1
Exemplo n.º 9
0
 def selectSwizzle(self):
     counted = self.count()
     rgba = 0
     if "r" in counted:
         rgba += counted["r"]
     if "g" in counted:
         rgba += counted["g"]
     if "b" in counted:
         rgba += counted["b"]
     if "a" in counted:
         rgba += counted["a"]
     stpq = 0
     if "s" in counted:
         stpq += counted["s"]
     if "t" in counted:
         stpq += counted["t"]
     if "p" in counted:
         stpq += counted["p"]
     if "q" in counted:
         stpq += counted["q"]
     xyzw = 0
     if "x" in counted:
         xyzw += counted["x"]
     if "y" in counted:
         xyzw += counted["y"]
     if "z" in counted:
         xyzw += counted["z"]
     if "w" in counted:
         xyzw += counted["w"]
     if (xyzw >= rgba) and (xyzw >= stpq):
         ret = ("x", "y", "z", "w")
         selected_for = xyzw
         selected_against = "rgba: %i, stpq: %i" % (rgba, stpq)
     elif (stpq >= xyzw) and (stpq >= rgba):
         ret = ("s", "t", "p", "q")
         selected_for = stpq
         selected_against = "rgba: %i, xyzw: %i" % (rgba, xyzw)
     else:
         ret = ("r", "g", "b", "a")
         selected_for = rgba
         selected_against = "stpq: %i, xyzw: %i" % (stpq, xyzw)
     if is_verbose():
         print("Selected GLSL swizzle: %s (%i vs. %s)" % (str(ret), selected_for, selected_against))
     return ret
Exemplo n.º 10
0
 def detectType(self):
     """Try to detect type from filename."""
     self.__type = None
     stub = r'.*[._\-\s]%s[._\-\s].*'
     if re.match(stub % ("frag"), self.__filename, re.I) or re.match(
             stub % ("fragment"), self.__filename, re.I):
         self.__type = "fragment"
     elif re.match(stub % ("geom"), self.__filename, re.I) or re.match(
             stub % ("geometry"), self.__filename, re.I):
         self.__type = "geometry"
     elif re.match(stub % ("vert"), self.__filename, re.I) or re.match(
             stub % ("vertex"), self.__filename, re.I):
         self.__type = "vertex"
     if is_verbose():
         output_message = "Shader file '%s' type" % (self.__filename)
         if self.__type:
             print(output_message + (": '%s'" % (self.__type)))
         else:
             print(output_message + " not detected, assuming generic.")
Exemplo n.º 11
0
 def minimal_align(self):
     """Remove all .align declarations, replace with desired alignment."""
     desired = int(PlatformVar("align"))
     adjustments = []
     for ii in range(len(self.__content)):
         line = self.__content[ii]
         match = re.match(r'(\s*)\.align\s+(\d+).*', line)
         if not match:
             continue
         # Get actual align byte count.
         align = get_align_bytes(int(match.group(2)))
         if align == desired:
             continue
         # Some alignment directives are necessary due to data access.
         if not can_minimize_align(align):
             continue
         self.__content[ii] = "%s.balign %i\n" % (match.group(1), desired)
         adjustments += ["%i -> %i" % (align, desired)]
     if is_verbose() and adjustments:
         print("Alignment adjustment(%s): %s" %
               (self.get_name(), ", ".join(adjustments)))
Exemplo n.º 12
0
 def merge(self, op):
     """Attempt to merge with given segment."""
     highest_mergable = 0
     (head_src, bytestream_src) = self.deconstruct_tail()
     (bytestream_dst, tail_dst) = op.deconstruct_head()
     for ii in range(min(len(bytestream_src), len(bytestream_dst))):
         mergable = True
         for jj in range(ii + 1):
             if not bytestream_src[-ii - 1 + jj].mergable(bytestream_dst[jj]):
                 mergable = False
                 break
         if mergable:
             highest_mergable = ii + 1
     if 0 >= highest_mergable:
         return False
     if is_verbose():
         print("Merging headers %s and %s at %i bytes." % (self.__name, op.__name, highest_mergable))
     for ii in range(highest_mergable):
         bytestream_src[-highest_mergable + ii].merge(bytestream_dst[ii])
     bytestream_dst[0:highest_mergable] = []
     self.reconstruct(head_src + bytestream_src)
     op.reconstruct(bytestream_dst + tail_dst)
     return True
Exemplo n.º 13
0
 def crunch(self, mode="full", max_inlines=-1, max_renames=-1, max_simplifys=-1):
     """Crunch the source code to smaller state."""
     combines = None
     inlines = None
     renames = None
     simplifys = None
     # Expand unless crunching completely disabled.
     if "none" != mode:
         for ii in self.__sources:
             ii.expandRecursive()
         # Perform inlining passes.
         inlines = 0
         while True:
             inline_pass_rv = self.inlinePass((max_inlines < 0) or (inlines < max_inlines))
             # Last pass will return a listing of merged variable names.
             if is_listing(inline_pass_rv):
                 merged = inline_pass_rv
                 break
             # Inlining was done, another round.
             inlines += 1
         # Perform simplification passes.
         simplifys = 0
         for ii in self.__sources:
             if (0 <= max_simplifys) and (simplifys >= max_simplifys):
                 break
             simplifys += simplify_pass(ii, max_simplifys - simplifys)
         # After all names have been collected, it's possible to select the best swizzle.
         swizzle = self.selectSwizzle()
         for ii in self.__sources:
             ii.selectSwizzle(swizzle)
         # Print number of inout merges.
         if is_verbose():
             inout_merges = []
             for ii in merged:
                 block = ii[0]
                 if is_listing(block):
                     inout_merges += [block[0]]
             if inout_merges:
                 print("GLSL inout connections found: %s" % (str(list(map(str, inout_merges)))))
         # Run rename passes until done.
         renames = 0
         for ii in merged:
             if (0 <= max_renames) and (renames >= max_renames):
                 break
             self.renamePass(ii[0], ii[1:])
             renames += 1
         # Run member rename passes until done.
         for ii in merged:
             block = ii[0]
             if is_listing(block):
                 block = block[0]
             if not is_glsl_block_inout_struct(block):
                 continue
             renames += self.renameMembers(block, max_renames - renames)
             # Also rename block type.
             if (0 > max_renames) or (renames < max_renames):
                 self.renameBlock(ii[0])
                 renames += 1
         # Perform recombine passes.
         for ii in self.__sources:
             combines = ii.collapseRecursive(mode)
     # Print summary of operations.
     if is_verbose():
         operations = []
         if inlines:
             operations += ["%i inlines" % (inlines)]
         if simplifys:
             operations += ["%i simplifys" % (simplifys)]
         if renames:
             operations += ["%i renames" % (renames)]
         if combines:
             operations += ["%i combines" % (combines)]
         if operations:
             print("GLSL processing done: %s" % (", ".join(operations)))