136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===-- MipsAsmBackend.cpp - Mips Asm Backend  ----------------------------===//
247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes//
347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes//                     The LLVM Compiler Infrastructure
447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes//
547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes// This file is distributed under the University of Illinois Open Source
647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes// License. See LICENSE.TXT for details.
747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes//
847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes//===----------------------------------------------------------------------===//
947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes//
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file implements the MipsAsmBackend class.
1147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes//
1247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes//===----------------------------------------------------------------------===//
1347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes//
1447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCTargetDesc/MipsFixupKinds.h"
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCTargetDesc/MipsAsmBackend.h"
1782ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka#include "MCTargetDesc/MipsMCTargetDesc.h"
1847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "llvm/MC/MCAsmBackend.h"
1982ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka#include "llvm/MC/MCAssembler.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCContext.h"
2182ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka#include "llvm/MC/MCDirectives.h"
2282ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka#include "llvm/MC/MCELFObjectWriter.h"
23f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCFixupKindInfo.h"
2482ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka#include "llvm/MC/MCObjectWriter.h"
2582ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka#include "llvm/MC/MCSubtargetInfo.h"
2682ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka#include "llvm/Support/ErrorHandling.h"
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/MathExtras.h"
2882ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka#include "llvm/Support/raw_ostream.h"
29e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes
3082ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanakausing namespace llvm;
3182ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka
32e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes// Prepare value for the target space for it
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                 MCContext *Ctx = nullptr) {
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Kind = Fixup.getKind();
3747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
3847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // Add/subtract and shift
3947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  switch (Kind) {
4047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  default:
41e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes    return 0;
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case FK_Data_2:
43e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes  case FK_GPRel_4:
44e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes  case FK_Data_4:
45e2245bab3ca29dc2142d8f254005f4ae7c40cde2Jack Carter  case FK_Data_8:
46e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes  case Mips::fixup_Mips_LO16:
474a50e53e53816076584c957741cb430899271726Jack Carter  case Mips::fixup_Mips_GPREL16:
480140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case Mips::fixup_Mips_GPOFF_HI:
490140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case Mips::fixup_Mips_GPOFF_LO:
500140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case Mips::fixup_Mips_GOT_PAGE:
510140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case Mips::fixup_Mips_GOT_OFST:
52fd506efec628819f7e6fad8016a9dbb5d8612b8bJack Carter  case Mips::fixup_Mips_GOT_DISP:
53198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case Mips::fixup_Mips_GOT_LO16:
54198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case Mips::fixup_Mips_CALL_LO16:
550082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_LO16:
560082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_GOT_PAGE:
570082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_GOT_OFST:
580082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_GOT_DISP:
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::fixup_MIPS_PCLO16:
6047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    break;
6147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  case Mips::fixup_Mips_PC16:
6247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // So far we are only using this type for branches.
6347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // For branches we start 1 instruction after the branch
6447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // so the displacement will be one instruction size less.
6547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    Value -= 4;
6647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // The displacement is then divided by 4 to give us an 18 bit
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // address range. Forcing a signed division because Value can be negative.
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value = (int64_t)Value / 4;
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // We now check if Value can be encoded as a 16-bit signed immediate.
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!isIntN(16, Value) && Ctx)
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Ctx->FatalError(Fixup.getLoc(), "out of range PC16 fixup");
7247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    break;
73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case Mips::fixup_MIPS_PC19_S2:
74cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // Forcing a signed division because Value can be negative.
75cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Value = (int64_t)Value / 4;
76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // We now check if Value can be encoded as a 19-bit signed immediate.
77cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!isIntN(19, Value) && Ctx)
78cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Ctx->FatalError(Fixup.getLoc(), "out of range PC19 fixup");
79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    break;
8047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  case Mips::fixup_Mips_26:
8147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // So far we are only using this type for jumps.
8247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // The displacement is then divided by 4 to give us an 28 bit
8347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // address range.
8447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    Value >>= 2;
8547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    break;
8684bfc2f090639f933df06cc675c4385511516befAkira Hatanaka  case Mips::fixup_Mips_HI16:
87e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes  case Mips::fixup_Mips_GOT_Local:
88198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case Mips::fixup_Mips_GOT_HI16:
89198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case Mips::fixup_Mips_CALL_HI16:
900082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_HI16:
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::fixup_MIPS_PCHI16:
92fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    // Get the 2nd 16-bits. Also add 1 if bit 15 is 1.
93bca9c25dabbf50923319339ae780d6f916f56bfbAkira Hatanaka    Value = ((Value + 0x8000) >> 16) & 0xffff;
9484bfc2f090639f933df06cc675c4385511516befAkira Hatanaka    break;
95fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter  case Mips::fixup_Mips_HIGHER:
96fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    // Get the 3rd 16-bits.
97fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    Value = ((Value + 0x80008000LL) >> 32) & 0xffff;
98fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    break;
99fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter  case Mips::fixup_Mips_HIGHEST:
100fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    // Get the 4th 16-bits.
101fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    Value = ((Value + 0x800080008000LL) >> 48) & 0xffff;
102fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    break;
1031aaf43c2a2ec0fd4c8dbfe56558237219c5f8af7Zoran Jovanovic  case Mips::fixup_MICROMIPS_26_S1:
1041aaf43c2a2ec0fd4c8dbfe56558237219c5f8af7Zoran Jovanovic    Value >>= 1;
1051aaf43c2a2ec0fd4c8dbfe56558237219c5f8af7Zoran Jovanovic    break;
1065c042162beb3c2dd556e00aab84c4278a69cd5b1Zoran Jovanovic  case Mips::fixup_MICROMIPS_PC16_S1:
1075c042162beb3c2dd556e00aab84c4278a69cd5b1Zoran Jovanovic    Value -= 4;
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Forcing a signed division because Value can be negative.
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value = (int64_t)Value / 2;
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // We now check if Value can be encoded as a 16-bit signed immediate.
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!isIntN(16, Value) && Ctx)
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Ctx->FatalError(Fixup.getLoc(), "out of range PC16 fixup");
1135c042162beb3c2dd556e00aab84c4278a69cd5b1Zoran Jovanovic    break;
114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case Mips::fixup_MIPS_PC18_S3:
115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // Forcing a signed division because Value can be negative.
116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Value = (int64_t)Value / 8;
117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // We now check if Value can be encoded as a 18-bit signed immediate.
118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!isIntN(18, Value) && Ctx)
119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Ctx->FatalError(Fixup.getLoc(), "out of range PC18 fixup");
120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    break;
121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::fixup_MIPS_PC21_S2:
122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value -= 4;
123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Forcing a signed division because Value can be negative.
124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value = (int64_t) Value / 4;
125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We now check if Value can be encoded as a 21-bit signed immediate.
126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isIntN(21, Value) && Ctx)
127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Ctx->FatalError(Fixup.getLoc(), "out of range PC21 fixup");
128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::fixup_MIPS_PC26_S2:
130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value -= 4;
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Forcing a signed division because Value can be negative.
132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value = (int64_t) Value / 4;
133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We now check if Value can be encoded as a 26-bit signed immediate.
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isIntN(26, Value) && Ctx)
135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Ctx->FatalError(Fixup.getLoc(), "out of range PC26 fixup");
136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
13747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  }
13847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
13947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  return Value;
14047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
14147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMCObjectWriter *MipsAsmBackend::createObjectWriter(raw_ostream &OS) const {
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return createMipsELFObjectWriter(OS,
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit);
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
146fb54afbcb8f460c5c4cafa605259ba0dd77504dcAkira Hatanaka
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Little-endian fixup data byte ordering:
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//   mips32r2:   a | b | x | x
14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//   microMIPS:  x | x | a | b
150e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool needsMMLEByteOrder(unsigned Kind) {
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Kind >= Mips::fixup_MICROMIPS_26_S1 &&
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         Kind < Mips::LastTargetFixupKind;
15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
155e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes
15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Calculate index for microMIPS specific little endian byte order
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic unsigned calculateMMLEIndex(unsigned i) {
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(i <= 3 && "Index out of range!");
159fb54afbcb8f460c5c4cafa605259ba0dd77504dcAkira Hatanaka
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (1 - i / 2) * 2 + i % 2;
16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
162e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ApplyFixup - Apply the \p Value for given \p Fixup into the provided
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// data fragment, at the offset specified by the fixup and following the
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// fixup kind as appropriate.
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                unsigned DataSize, uint64_t Value,
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                bool IsPCRel) const {
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCFixupKind Kind = Fixup.getKind();
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value = adjustFixupValue(Fixup, Value);
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!Value)
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return; // Doesn't change encoding.
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Where do we start in the object
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Offset = Fixup.getOffset();
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Number of bytes we need to fixup
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8;
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Used to point to big endian bytes
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned FullSize;
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch ((unsigned)Kind) {
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case FK_Data_2:
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Mips::fixup_Mips_16:
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    FullSize = 2;
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case FK_Data_8:
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Mips::fixup_Mips_64:
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    FullSize = 8;
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case FK_Data_4:
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    FullSize = 4;
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
195fb54afbcb8f460c5c4cafa605259ba0dd77504dcAkira Hatanaka  }
19647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Grab current value, if any, from bits.
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t CurVal = 0;
19947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
20147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0; i != NumBytes; ++i) {
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                    : i)
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                            : (FullSize - 1 - i);
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
2074b6ee7a35213709c057cdd073fb27bda09fa3359Akira Hatanaka  }
2084b6ee7a35213709c057cdd073fb27bda09fa3359Akira Hatanaka
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Mask = ((uint64_t)(-1) >>
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    (64 - getFixupKindInfo(Kind).TargetSize));
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CurVal |= Value & Mask;
212370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Write out the fixed up bytes back to the code/data bits.
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0; i != NumBytes; ++i) {
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                    : i)
21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                            : (FullSize - 1 - i);
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
2194b6ee7a35213709c057cdd073fb27bda09fa3359Akira Hatanaka  }
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
221bb481f882093fb738d2bb15610c79364bada5496Jia Liu
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst MCFixupKindInfo &MipsAsmBackend::
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesgetFixupKindInfo(MCFixupKind Kind) const {
224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const static MCFixupKindInfo LittleEndianInfos[Mips::NumTargetFixupKinds] = {
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // This table *must* be in same the order of fixup_* kinds in
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // MipsFixupKinds.h.
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    //
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // name                    offset  bits  flags
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_16",           0,     16,   0 },
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_32",           0,     32,   0 },
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_REL32",        0,     32,   0 },
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_26",           0,     26,   0 },
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_HI16",         0,     16,   0 },
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_LO16",         0,     16,   0 },
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GPREL16",      0,     16,   0 },
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_LITERAL",      0,     16,   0 },
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GOT_Global",   0,     16,   0 },
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GOT_Local",    0,     16,   0 },
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_PC16",         0,     16,  MCFixupKindInfo::FKF_IsPCRel },
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_CALL16",       0,     16,   0 },
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GPREL32",      0,     32,   0 },
24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_SHIFT5",       6,      5,   0 },
24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_SHIFT6",       6,      5,   0 },
24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_64",           0,     64,   0 },
24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_TLSGD",        0,     16,   0 },
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GOTTPREL",     0,     16,   0 },
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_TPREL_HI",     0,     16,   0 },
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_TPREL_LO",     0,     16,   0 },
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_TLSLDM",       0,     16,   0 },
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_DTPREL_HI",    0,     16,   0 },
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_DTPREL_LO",    0,     16,   0 },
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_Branch_PCRel", 0,     16,  MCFixupKindInfo::FKF_IsPCRel },
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GPOFF_HI",     0,     16,   0 },
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GPOFF_LO",     0,     16,   0 },
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GOT_PAGE",     0,     16,   0 },
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GOT_OFST",     0,     16,   0 },
25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GOT_DISP",     0,     16,   0 },
25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_HIGHER",       0,     16,   0 },
25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_HIGHEST",      0,     16,   0 },
26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GOT_HI16",     0,     16,   0 },
26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_GOT_LO16",     0,     16,   0 },
26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_CALL_HI16",    0,     16,   0 },
26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_Mips_CALL_LO16",    0,     16,   0 },
264cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    { "fixup_Mips_PC18_S3",      0,     18,  MCFixupKindInfo::FKF_IsPCRel },
265cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    { "fixup_MIPS_PC19_S2",      0,     19,  MCFixupKindInfo::FKF_IsPCRel },
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MIPS_PC21_S2",      0,     21,  MCFixupKindInfo::FKF_IsPCRel },
267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MIPS_PC26_S2",      0,     26,  MCFixupKindInfo::FKF_IsPCRel },
268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MIPS_PCHI16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MIPS_PCLO16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_26_S1",   0,     26,   0 },
27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_HI16",    0,     16,   0 },
27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_LO16",    0,     16,   0 },
27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_GOT16",   0,     16,   0 },
27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_PC16_S1", 0,     16,   MCFixupKindInfo::FKF_IsPCRel },
27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_CALL16",  0,     16,   0 },
27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_GOT_DISP",        0,     16,   0 },
27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_GOT_PAGE",        0,     16,   0 },
27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_GOT_OFST",        0,     16,   0 },
27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_TLS_GD",          0,     16,   0 },
28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_TLS_LDM",         0,     16,   0 },
28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0,     16,   0 },
28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0,     16,   0 },
28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_TLS_TPREL_HI16",  0,     16,   0 },
28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    { "fixup_MICROMIPS_TLS_TPREL_LO16",  0,     16,   0 }
28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const static MCFixupKindInfo BigEndianInfos[Mips::NumTargetFixupKinds] = {
288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // This table *must* be in same the order of fixup_* kinds in
289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // MipsFixupKinds.h.
290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    //
291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // name                    offset  bits  flags
292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_16",          16,     16,   0 },
293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_32",           0,     32,   0 },
294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_REL32",        0,     32,   0 },
295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_26",           6,     26,   0 },
296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_HI16",        16,     16,   0 },
297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_LO16",        16,     16,   0 },
298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GPREL16",     16,     16,   0 },
299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_LITERAL",     16,     16,   0 },
300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GOT_Global",  16,     16,   0 },
301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GOT_Local",   16,     16,   0 },
302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_PC16",        16,     16,  MCFixupKindInfo::FKF_IsPCRel },
303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_CALL16",      16,     16,   0 },
304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GPREL32",      0,     32,   0 },
305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_SHIFT5",      21,      5,   0 },
306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_SHIFT6",      21,      5,   0 },
307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_64",           0,     64,   0 },
308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_TLSGD",       16,     16,   0 },
309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GOTTPREL",    16,     16,   0 },
310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_TPREL_HI",    16,     16,   0 },
311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_TPREL_LO",    16,     16,   0 },
312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_TLSLDM",      16,     16,   0 },
313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_DTPREL_HI",   16,     16,   0 },
314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_DTPREL_LO",   16,     16,   0 },
315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_Branch_PCRel",16,     16,  MCFixupKindInfo::FKF_IsPCRel },
316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GPOFF_HI",    16,     16,   0 },
317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GPOFF_LO",    16,     16,   0 },
318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GOT_PAGE",    16,     16,   0 },
319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GOT_OFST",    16,     16,   0 },
320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GOT_DISP",    16,     16,   0 },
321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_HIGHER",      16,     16,   0 },
322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_HIGHEST",     16,     16,   0 },
323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GOT_HI16",    16,     16,   0 },
324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_GOT_LO16",    16,     16,   0 },
325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_CALL_HI16",   16,     16,   0 },
326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_Mips_CALL_LO16",   16,     16,   0 },
327cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    { "fixup_Mips_PC18_S3",     14,     18,  MCFixupKindInfo::FKF_IsPCRel },
328cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    { "fixup_MIPS_PC19_S2",     13,     19,  MCFixupKindInfo::FKF_IsPCRel },
329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MIPS_PC21_S2",     11,     21,  MCFixupKindInfo::FKF_IsPCRel },
330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MIPS_PC26_S2",      6,     26,  MCFixupKindInfo::FKF_IsPCRel },
331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MIPS_PCHI16",      16,     16,  MCFixupKindInfo::FKF_IsPCRel },
332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MIPS_PCLO16",      16,     16,  MCFixupKindInfo::FKF_IsPCRel },
333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_26_S1",   6,     26,   0 },
334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_HI16",   16,     16,   0 },
335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_LO16",   16,     16,   0 },
336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_GOT16",  16,     16,   0 },
337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_PC16_S1",16,     16,   MCFixupKindInfo::FKF_IsPCRel },
338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_CALL16", 16,     16,   0 },
339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_GOT_DISP",        16,     16,   0 },
340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_GOT_PAGE",        16,     16,   0 },
341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_GOT_OFST",        16,     16,   0 },
342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_TLS_GD",          16,     16,   0 },
343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_TLS_LDM",         16,     16,   0 },
344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16,     16,   0 },
345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16,     16,   0 },
346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_TLS_TPREL_HI16",  16,     16,   0 },
347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    { "fixup_MICROMIPS_TLS_TPREL_LO16",  16,     16,   0 }
348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Kind < FirstTargetFixupKind)
35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MCAsmBackend::getFixupKindInfo(Kind);
35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          "Invalid kind!");
355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IsLittle)
357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return LittleEndianInfos[Kind - FirstTargetFixupKind];
358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return BigEndianInfos[Kind - FirstTargetFixupKind];
35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
3601d82115042c81793cc3d807a8136f7f0f475f083Jack Carter
36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// WriteNopData - Write an (optimal) nop sequence of Count bytes
36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// to the given output. If the target cannot generate such a sequence,
36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// it should return an error.
36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///
36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \return - True on success.
36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Check for a less than instruction size number of bytes
36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: 16 bit instructions are not handled yet here.
36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We shouldn't be using a hard coded number for instruction size.
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Count % 4) return false;
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t NumNops = Count / 4;
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (uint64_t i = 0; i != NumNops; ++i)
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OW->Write32(0);
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
37782ea7314ca52c9df8e1b6600231fafb7ae722313Akira Hatanaka
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// processFixupValue - Target hook to process the literal value of a fixup
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// if necessary.
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmBackend::processFixupValue(const MCAssembler &Asm,
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       const MCAsmLayout &Layout,
38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       const MCFixup &Fixup,
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       const MCFragment *DF,
38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       const MCValue &Target,
38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       uint64_t &Value,
38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       bool &IsResolved) {
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // At this point we'll ignore the value returned by adjustFixupValue as
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // we are only checking if the fixup can be applied correctly. We have
38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // access to MCContext from here which allows us to report a fatal error
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // with *possibly* a source code location.
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  (void)adjustFixupValue(Fixup, Value, &Asm.getContext());
39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
3934b6ee7a35213709c057cdd073fb27bda09fa3359Akira Hatanaka
394e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka// MCAsmBackend
395c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill WendlingMCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T,
396c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling                                             const MCRegisterInfo &MRI,
397c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling                                             StringRef TT,
398536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky                                             StringRef CPU) {
399e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka  return new MipsAsmBackend(T, Triple(TT).getOS(),
400a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka                            /*IsLittle*/true, /*Is64Bit*/false);
40129a17145ad4985df032785cc1b4716fd7875d47bRafael Espindola}
4024b6ee7a35213709c057cdd073fb27bda09fa3359Akira Hatanaka
403c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill WendlingMCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T,
404c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling                                             const MCRegisterInfo &MRI,
405c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling                                             StringRef TT,
406536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky                                             StringRef CPU) {
407e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka  return new MipsAsmBackend(T, Triple(TT).getOS(),
408a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka                            /*IsLittle*/false, /*Is64Bit*/false);
4094b6ee7a35213709c057cdd073fb27bda09fa3359Akira Hatanaka}
410a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka
411c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill WendlingMCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T,
412c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling                                             const MCRegisterInfo &MRI,
413c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling                                             StringRef TT,
414536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky                                             StringRef CPU) {
415a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka  return new MipsAsmBackend(T, Triple(TT).getOS(),
416a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka                            /*IsLittle*/true, /*Is64Bit*/true);
417a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka}
418a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka
419c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill WendlingMCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T,
420c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling                                             const MCRegisterInfo &MRI,
421c3cee57f7d20f69a84fd88464ed8cf050e63c7adBill Wendling                                             StringRef TT,
422536a88ad5bf160232205192a7ce72e50bfadbdedRoman Divacky                                             StringRef CPU) {
423a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka  return new MipsAsmBackend(T, Triple(TT).getOS(),
424a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka                            /*IsLittle*/false, /*Is64Bit*/true);
425a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka}
426