parameters: (llvm_mc, f, triple)
docstring: Extract all instructions from `f`, feed them to `llvm-mc` and make sure it's
    encoded them the same way as VIXL. `triple` allows us to specify either
    "thumbv8" or "armv8".
docstring_summary: Extract all instructions from `f`, feed them to `llvm-mc` and make sure it's
    encoded them the same way as VIXL. `triple` allows us to specify either
    "thumbv8" or "armv8".
docstring_tokens: Extract all instructions from f feed them to llvm - mc and make sure it s encoded them the same way as VIXL . triple allows us to specify either thumbv8 or armv8 .
function: def VerifyInstructionsWithLLVMMC(llvm_mc, f, triple):
    """
    Extract all instructions from `f`, feed them to `llvm-mc` and make sure it's
    encoded them the same way as VIXL. `triple` allows us to specify either
    "thumbv8" or "armv8".
    """
  
    vixl_reference = ReadTrace(f.read())
    vixl_instructions, vixl_encodings = zip(*vixl_reference)
    instructions = [
        ConvertToLLVMFormat(instruction, triple)
        for instruction in vixl_instructions
    ]
    llvm_mc_proc = subprocess.Popen(
        [llvm_mc, '-assemble', '-triple={}'.format(triple), '-mattr=v8,crc',
         # LLVM fails to recognize some instructions as valid T32 when we do not
         # set `-mcpu`.
         '-mcpu=cortex-a53', '-show-encoding'],
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = llvm_mc_proc.communicate("\n".join(instructions).encode())
    # If `llvm-mc` printed something to stderr then stop.
    if err:
      print(err.decode())
      return
  
    # Extract list of bytes from `llvm-mc` output. It's in the following form:
    #
    #         clzeq   r0, r0                  @ encoding: [0x10,0x0f,0x6f,0x01]
    #                                                      ^^^^ ^^^^ ^^^^ ^^^^
    llvm_encodings = [
        match_object.group('encoding').replace(" ", "").split(",")
        for match_object in re.finditer(".*@ encoding: \[(?P<encoding>.*)\]",
                                        out.decode())
    ]
  
    # If LLVM has generated exactly twice as much instructions, we assume this is
    # due to IT instructions preceding every instruction under test. VIXL's
    # assembly reference files will contain a single array of 4 bytes encoding
    # both the IT and the following instruction. While LLVM will have decoded them
    # into two seperate 2 bytes arrays.
    if len(llvm_encodings) == 2 * len(vixl_encodings):
      llvm_encodings = [
          llvm_encodings[i * 2] + llvm_encodings[(i * 2) + 1]
          for i in range(0, len(vixl_encodings))
      ]
  
    # Check the encodings from LLVM are identical to VIXL's.
    if len(llvm_encodings) != len(vixl_encodings):
      print("""Error: llvm-mc generated {} instructions than there are in the
  generated trace.
          """.format("fewer" if len(llvm_encodings) < len(vixl_encodings) else "more"))
    else:
      for i in range(0, len(vixl_encodings)):
        if llvm_encodings[i] != vixl_encodings[i]:
          print("""Error: llvm-mc disagrees on the encoding of \"{instruction}\":
    LLVM-MC: {llvm}
    VIXL:    {vixl}
              """.format(instruction=vixl_instructions[i].replace("\n", "; "),
                         llvm=llvm_encodings[i],
                         vixl=vixl_encodings[i]))
function_tokens: def VerifyInstructionsWithLLVMMC ( llvm_mc , f , triple ) : vixl_reference = ReadTrace ( f . read ( ) ) vixl_instructions , vixl_encodings = zip ( * vixl_reference ) instructions = [ ConvertToLLVMFormat ( instruction , triple ) for instruction in vixl_instructions ] llvm_mc_proc = subprocess . Popen ( [ llvm_mc , '-assemble' , '-triple={}' . format ( triple ) , '-mattr=v8,crc' , # LLVM fails to recognize some instructions as valid T32 when we do not # set `-mcpu`. '-mcpu=cortex-a53' , '-show-encoding' ] , stdin = subprocess . PIPE , stdout = subprocess . PIPE , stderr = subprocess . PIPE ) out , err = llvm_mc_proc . communicate ( "\n" . join ( instructions ) . encode ( ) ) # If `llvm-mc` printed something to stderr then stop. if err : print ( err . decode ( ) ) return # Extract list of bytes from `llvm-mc` output. It's in the following form: # #         clzeq   r0, r0                  @ encoding: [0x10,0x0f,0x6f,0x01] #                                                      ^^^^ ^^^^ ^^^^ ^^^^ llvm_encodings = [ match_object . group ( 'encoding' ) . replace ( " " , "" ) . split ( "," ) for match_object in re . finditer ( ".*@ encoding: \[(?P<encoding>.*)\]" , out . decode ( ) ) ] # If LLVM has generated exactly twice as much instructions, we assume this is # due to IT instructions preceding every instruction under test. VIXL's # assembly reference files will contain a single array of 4 bytes encoding # both the IT and the following instruction. While LLVM will have decoded them # into two seperate 2 bytes arrays. if len ( llvm_encodings ) == 2 * len ( vixl_encodings ) : llvm_encodings = [ llvm_encodings [ i * 2 ] + llvm_encodings [ ( i * 2 ) + 1 ] for i in range ( 0 , len ( vixl_encodings ) ) ] # Check the encodings from LLVM are identical to VIXL's. if len ( llvm_encodings ) != len ( vixl_encodings ) : print ( """Error: llvm-mc generated {} instructions than there are in the
  generated trace.
          """ . format ( "fewer" if len ( llvm_encodings ) < len ( vixl_encodings ) else "more" ) ) else : for i in range ( 0 , len ( vixl_encodings ) ) : if llvm_encodings [ i ] != vixl_encodings [ i ] : print ( """Error: llvm-mc disagrees on the encoding of \"{instruction}\":
    LLVM-MC: {llvm}
    VIXL:    {vixl}
              """ . format ( instruction = vixl_instructions [ i ] . replace ( "\n" , "; " ) , llvm = llvm_encodings [ i ] , vixl = vixl_encodings [ i ] ) )