From ab1096fdf6d3e2d6acb67e8bdf884af8bbc2d8fe Mon Sep 17 00:00:00 2001 From: qhuang8 Date: Wed, 28 Jun 2006 09:41:50 +0000 Subject: 1.BaseMemoryLibMmx: Add X64 Cpu Arch support. 2.BasePrintLib: Fix some minor bugs git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@651 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/BaseMemoryLibMmx/BaseMemoryLibMmx.msa | 36 ++++++++---- MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.asm | 43 ++++++++++++++ MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.asm | 68 ++++++++++++++++++++++ MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.asm | 42 +++++++++++++ MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.asm | 42 +++++++++++++ MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.asm | 42 +++++++++++++ MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.asm | 42 +++++++++++++ MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.asm | 49 ++++++++++++++++ MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.asm | 48 +++++++++++++++ MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.asm | 47 +++++++++++++++ MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.asm | 39 +++++++++++++ MdePkg/Library/BasePrintLib/PrintLib.c | 26 +++++++-- MdePkg/Library/BasePrintLib/PrintLibInternal.c | 6 +- 13 files changed, 513 insertions(+), 17 deletions(-) create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.asm create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.asm create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.asm create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.asm create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.asm create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.asm create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.asm create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.asm create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.asm create mode 100644 MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.asm diff --git a/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.msa b/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.msa index d212557777..c0e89c3ffc 100644 --- a/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.msa +++ b/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.msa @@ -36,19 +36,19 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. DebugLib + MemLibGuid.c + CopyMemWrapper.c + SetMemWrapper.c + SetMem16Wrapper.c + SetMem32Wrapper.c + SetMem64Wrapper.c + CompareMemWrapper.c + ZeroMemWrapper.c + ScanMem8Wrapper.c + ScanMem16Wrapper.c + ScanMem32Wrapper.c + ScanMem64Wrapper.c - MemLibGuid.c - CopyMemWrapper.c - SetMemWrapper.c - SetMem16Wrapper.c - SetMem32Wrapper.c - SetMem64Wrapper.c - CompareMemWrapper.c - ZeroMemWrapper.c - ScanMem8Wrapper.c - ScanMem16Wrapper.c - ScanMem32Wrapper.c - ScanMem64Wrapper.c Ia32/CopyMem.asm Ia32/SetMem.asm Ia32/ZeroMem.asm @@ -61,6 +61,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Ia32/ScanMem32.asm Ia32/ScanMem64.asm + + X64/CopyMem.asm + X64/SetMem.asm + X64/SetMem16.asm + X64/SetMem32.asm + X64/SetMem64.asm + X64/CompareMem.asm + X64/ScanMem8.asm + X64/ScanMem16.asm + X64/ScanMem32.asm + X64/ScanMem64.asm + MdePkg diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.asm new file mode 100644 index 0000000000..b8e289bb27 --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.asm @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; CompareMem.Asm +; +; Abstract: +; +; CompareMem function +; +; Notes: +; +; The following BaseMemoryLib instances share the same version of this file: +; +; BaseMemoryLibRepStr +; BaseMemoryLibMmx +; BaseMemoryLibSse2 +; +;------------------------------------------------------------------------------ + + .code + +InternalMemCompareMem PROC USES rsi rdi + mov rsi, rcx + mov rdi, rdx + mov rcx, r8 + repe cmpsb + movzx rax, byte ptr [rsi - 1] + movzx rdx, byte ptr [rdi - 1] + sub rax, rdx + ret +InternalMemCompareMem ENDP + + END diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.asm new file mode 100644 index 0000000000..372c365203 --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.asm @@ -0,0 +1,68 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; CopyMem.asm +; +; Abstract: +; +; CopyMem function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +InternalMemCopyMem PROC USES rsi rdi + mov rsi, rdx ; rsi <- Source + mov rdi, rcx ; rdi <- Destination + lea r9, [rdi + r8 - 1] ; r9 <- End of Destination + cmp rsi, rdi + mov rax, rdi ; rax <- Destination as return value + jae @F + cmp r9, rsi + jae @CopyBackward ; Copy backward if overlapped +@@: + xor rcx, rcx + sub rcx, rsi + and rcx, 7 ; rcx + rsi aligns on 8-byte boundary + jz @F + cmp rcx, r8 + cmova rcx, r8 + sub r8, rcx ; r8 <- remaining bytes to copy + rep movsb +@@: + mov rcx, r8 + and r8, 7 + shr rcx, 3 ; rcx <- # of Qwords to copy + jz @CopyBytes +@@: + DB 48h, 0fh, 6fh, 06h ; movq mm0, [rsi] + DB 48h, 0fh, 0e7h, 07h ; movntq [rdi], mm0 + add rsi, 8 + add rdi, 8 + loop @B + mfence + jmp @CopyBytes +@CopyBackward: + mov rdi, r9 ; rdi <- End of Destination + lea rsi, [rsi + r8 - 1] ; rsi <- End of Source + std ; set direction flag +@CopyBytes: + mov rcx, r8 + rep movsb ; Copy bytes backward + cld + ret +InternalMemCopyMem ENDP + + END diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.asm new file mode 100644 index 0000000000..6af88fae5b --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; ScanMem16.Asm +; +; Abstract: +; +; ScanMem16 function +; +; Notes: +; +; The following BaseMemoryLib instances share the same version of this file: +; +; BaseMemoryLibRepStr +; BaseMemoryLibMmx +; BaseMemoryLibSse2 +; +;------------------------------------------------------------------------------ + + .code + +InternalMemScanMem16 PROC USES rdi + mov rdi, rcx + mov rax, r8 + mov rcx, rdx + repne scasw + lea rax, [rdi - 2] + cmovnz rax, rcx + ret +InternalMemScanMem16 ENDP + + END diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.asm new file mode 100644 index 0000000000..f9c9feb00e --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; ScanMem32.Asm +; +; Abstract: +; +; ScanMem32 function +; +; Notes: +; +; The following BaseMemoryLib instances share the same version of this file: +; +; BaseMemoryLibRepStr +; BaseMemoryLibMmx +; BaseMemoryLibSse2 +; +;------------------------------------------------------------------------------ + + .code + +InternalMemScanMem32 PROC USES rdi + mov rdi, rcx + mov rax, r8 + mov rcx, rdx + repne scasd + lea rax, [rdi - 4] + cmovnz rax, rcx + ret +InternalMemScanMem32 ENDP + + END diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.asm new file mode 100644 index 0000000000..2f286c9e2f --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; ScanMem64.Asm +; +; Abstract: +; +; ScanMem64 function +; +; Notes: +; +; The following BaseMemoryLib instances share the same version of this file: +; +; BaseMemoryLibRepStr +; BaseMemoryLibMmx +; BaseMemoryLibSse2 +; +;------------------------------------------------------------------------------ + + .code + +InternalMemScanMem64 PROC USES rdi + mov rdi, rcx + mov rax, r8 + mov rcx, rdx + repne scasq + lea rax, [rdi - 8] + cmovnz rax, rcx + ret +InternalMemScanMem64 ENDP + + END diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.asm new file mode 100644 index 0000000000..4027ece768 --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; ScanMem8.Asm +; +; Abstract: +; +; ScanMem8 function +; +; Notes: +; +; The following BaseMemoryLib instances share the same version of this file: +; +; BaseMemoryLibRepStr +; BaseMemoryLibMmx +; BaseMemoryLibSse2 +; +;------------------------------------------------------------------------------ + + .code + +InternalMemScanMem8 PROC USES rdi + mov rdi, rcx + mov rcx, rdx + mov rax, r8 + repne scasb + lea rax, [rdi - 1] + cmovnz rax, rcx ; set rax to 0 if not found + ret +InternalMemScanMem8 ENDP + + END diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.asm new file mode 100644 index 0000000000..9688c3d65b --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.asm @@ -0,0 +1,49 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; SetMem.asm +; +; Abstract: +; +; SetMem function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +InternalMemSetMem PROC USES rdi + mov rax, r8 + mov ah, al + DB 48h, 0fh, 6eh, 0c0h ; movq mm0, rax + mov r8, rcx + mov rdi, r8 + mov rcx, rdx + shr rcx, 3 + jz @SetBytes + DB 0fh, 70h, 0C0h, 00h ; pshufw mm0, mm0, 0h +@@: + DB 48h, 0fh, 0e7h, 07h ; movntq [rdi], mm0 + add rdi, 8 + loop @B + mfence +@SetBytes: + and rdx, 7 + mov rcx, rdx + rep stosb + mov rax, r8 + ret +InternalMemSetMem ENDP + + END diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.asm new file mode 100644 index 0000000000..a95020876c --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.asm @@ -0,0 +1,48 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; SetMem16.asm +; +; Abstract: +; +; SetMem16 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +InternalMemSetMem16 PROC USES rdi + mov rax, r8 + DB 48h, 0fh, 6eh, 0c0h ; movq mm0, rax + mov r8, rcx + mov rdi, r8 + mov rcx, rdx + and rdx, 3 + shr rcx, 2 + jz @SetWords + DB 0fh, 70h, 0C0h, 00h ; pshufw mm0, mm0, 0h +@@: + DB 48h, 0fh, 0e7h, 07h ; movntq [rdi], mm0 + add rdi, 8 + loop @B + mfence +@SetWords: + mov rcx, rdx + rep stosw + mov rax, r8 + ret +InternalMemSetMem16 ENDP + + END diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.asm new file mode 100644 index 0000000000..d835543767 --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.asm @@ -0,0 +1,47 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; SetMem32.asm +; +; Abstract: +; +; SetMem32 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +InternalMemSetMem32 PROC USES rdi + DB 49h, 0fh, 6eh, 0c0h ; movq mm0, r8 ; mm0 <- Value + mov rax, rcx ; rax <- Buffer + mov rdi, rax + mov rcx, rdx + shr rcx, 1 + jz @SetDwords + DB 0fh, 70h, 0C0h, 44h ; pshufw mm0, mm0, 44h +@@: + DB 48h, 0fh, 0e7h, 07h ; movntq [rdi], mm0 + add rdi, 8 + loop @B + mfence +@SetDwords: + test dl, 1 + jz @F + DB 0fh, 7eh, 07h ; movd [rdi], mm0 +@@: + ret +InternalMemSetMem32 ENDP + + END diff --git a/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.asm b/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.asm new file mode 100644 index 0000000000..5780647445 --- /dev/null +++ b/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; SetMem64.asm +; +; Abstract: +; +; SetMem64 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +InternalMemSetMem64 PROC USES rdi + DB 49h, 0fh, 6eh, 0c0h; movq mm0, r8 ; mm0 <- Value + mov rax, rcx ; rax <- Buffer + xchg rcx, rdx ; rcx <- Count + mov rdi, rax +@@: + DB 48h, 0fh, 0e7h, 07h; movntq [rdi], mm0 + add rdi, 8 + loop @B + mfence + ret +InternalMemSetMem64 ENDP + + END diff --git a/MdePkg/Library/BasePrintLib/PrintLib.c b/MdePkg/Library/BasePrintLib/PrintLib.c index bbafeeaec5..1484d891b6 100644 --- a/MdePkg/Library/BasePrintLib/PrintLib.c +++ b/MdePkg/Library/BasePrintLib/PrintLib.c @@ -227,6 +227,17 @@ BasePrintLibVSPrint ( Precision = Count; } break; + + case '\0': + // + // Make no output if Format string terminates unexpectedly when + // looking up for flag, width, precision and type. + // + Format -= BytesPerFormatCharacter; + Precision = 0; + // + // break skiped on purpose. + // default: Done = TRUE; break; @@ -299,19 +310,26 @@ BasePrintLibVSPrint ( Count = 0; } ArgumentString = (CHAR8 *)ValueBuffer + Count; - Digits = 3 - (Count % 3); + + Digits = Count % 3; + if (Digits != 0) { + Digits = 3 - Digits; + } if (Comma && Count != 0) { Count += ((Count - 1) / 3); } if (Prefix != 0) { Count++; + Precision++; } Flags |= ARGUMENT_REVERSED; ZeroPad = TRUE; if ((Flags & PREFIX_ZERO) != 0) { - if ((Flags & PAD_TO_WIDTH) != 0) { - if ((Flags & PRECISION) == 0) { - Precision = Width; + if ((Flags & LEFT_JUSTIFY) == 0) { + if ((Flags & PAD_TO_WIDTH) != 0) { + if ((Flags & PRECISION) == 0) { + Precision = Width; + } } } } diff --git a/MdePkg/Library/BasePrintLib/PrintLibInternal.c b/MdePkg/Library/BasePrintLib/PrintLibInternal.c index 9314b60911..30b4539141 100644 --- a/MdePkg/Library/BasePrintLib/PrintLibInternal.c +++ b/MdePkg/Library/BasePrintLib/PrintLibInternal.c @@ -158,6 +158,7 @@ BasePrintLibConvertValueToString ( if (Value < 0) { Value = -Value; Buffer = BasePrintLibFillBuffer (Buffer, 1, '-', Increment); + Width--; } Count = BasePrintLibValueToString (ValueBuffer, Value, 10); @@ -166,7 +167,10 @@ BasePrintLibConvertValueToString ( Buffer = BasePrintLibFillBuffer (Buffer, Width - Count, '0', Increment); } - Digits = 3 - (Count % 3); + Digits = Count % 3; + if (Digits != 0) { + Digits = 3 - Digits; + } for (Index = 0; Index < Count; Index++) { Buffer = BasePrintLibFillBuffer (Buffer, 1, ValueBuffer[Count - Index], Increment); if ((Flags & COMMA_TYPE) != 0) { -- cgit v1.2.3