Commit Graph

211823 Commits

Author SHA1 Message Date
Maksim Panchenko cce239c45d HHVM calling conventions.
HHVM calling convention, hhvmcc, is used by HHVM JIT for
functions in translated cache. We currently support LLVM back end to
generate code for X86-64 and may support other architectures in the
future.

In HHVM calling convention any GP register could be used to pass and
return values, with the exception of R12 which is reserved for
thread-local area and is callee-saved. Other than R12, we always
pass RBX and RBP as args, which are our virtual machine's stack pointer
and frame pointer respectively.

When we enter translation cache via hhvmcc function, we expect
the stack to be aligned at 16 bytes, i.e. skewed by 8 bytes as opposed
to standard ABI alignment. This affects stack object alignment and stack
adjustments for function calls.

One extra calling convention, hhvm_ccc, is used to call C++ helpers from
HHVM's translation cache. It is almost identical to standard C calling
convention with an exception of first argument which is passed in RBP
(before we use RDI, RSI, etc.)

Differential Revision: http://reviews.llvm.org/D12681

llvm-svn: 248832
2015-09-29 22:09:16 +00:00
Rui Ueyama 4eed0114c5 ELF2: Use 'a.out' as default output file name.
llvm-svn: 248831
2015-09-29 21:49:40 +00:00
Alexey Samsonov 4133c18b1c [CFI] Make CFI tests require UBSan (for diagnostic mode).
CFI itself, on the other hand, doesn't require anything, including
sanitizer_common.

llvm-svn: 248830
2015-09-29 21:43:37 +00:00
Evgeniy Stepanov 7aba3960c7 [msan] Early allocator initialization.
Map MSan heap space early (in __msan_init) so that user code can not
accidentally (i.e. w/o MAP_FIXED) create a conflicting mapping.

llvm-svn: 248829
2015-09-29 21:28:54 +00:00
Hans Wennborg 59dbe86325 Fix Clang-tidy modernize-use-nullptr warnings in headers and generated files; other minor cleanups.
By Eugene Zelenko!

Differential Revision: http://reviews.llvm.org/D13187

llvm-svn: 248828
2015-09-29 20:56:43 +00:00
Chad Rosier 1769d8505f Fix test from r248825.
llvm-svn: 248827
2015-09-29 20:50:15 +00:00
Adrian Prantl 9e8ea3599e CGDebugInfo: Don't reuse a reference into a DenseMap if the DenseMap may
be modified in between. (NFC)

llvm-svn: 248826
2015-09-29 20:44:46 +00:00
Chad Rosier 4315012769 [AArch64] Add support for pre- and post-index LDPSWs.
llvm-svn: 248825
2015-09-29 20:39:55 +00:00
David Majnemer a80c151286 [WinEH] Teach AsmPrinter about funclets
Summary:
Funclets have been turned into functions by the time they hit the object
file.  Make sure that they have decent names for the symbol table and
CFI directives explaining how to reason about their prologues.

Differential Revision: http://reviews.llvm.org/D13261

llvm-svn: 248824
2015-09-29 20:12:33 +00:00
Tobias Grosser 81f005617e Replace default destructors by {} destructors
Hope this fixes the buildbots for now.

llvm-svn: 248823
2015-09-29 19:52:09 +00:00
Zachary Turner 4dddcc64d3 [llvm-pdbdump] Add include-only filters.
PDB files have a lot of noise in them, with hundreds (or thousands)
of symbols from system libraries and compiler generated types.  If
you're only looking for a specific type, this can be problematic.

This CL allows you to display *only* types, variables, or compilands
matching a particular pattern.  These filters can even be combined
with exclude filters.  Include-only filters are given priority, so
that first the set of items to display is limited only to those that
match the include filters, and then the set of exclude filters is
applied to those.  If there are no include filters specified, then
it means "display everything".

llvm-svn: 248822
2015-09-29 19:49:06 +00:00
Cong Hou 166e08542e Rename some function arguments in MachineBasicBlock.cpp/h by turning the first letter into upper case. NFC.
llvm-svn: 248821
2015-09-29 19:46:09 +00:00
Rafael Espindola 2d73648667 Update test to use invalid elf file in archives.
The code in driver is about to change so that the invalid files would no
longer be seen as ELF.

This makes sure that the error path will remain tested.

llvm-svn: 248820
2015-09-29 18:44:18 +00:00
Renato Golin 9be32f6317 Add armhf as unstable runtime temporarily
llvm-svn: 248819
2015-09-29 18:35:55 +00:00
Dehao Chen 8e7df83e6a http://reviews.llvm.org/D13231
Change lookup functions to const functions.

llvm-svn: 248818
2015-09-29 18:28:15 +00:00
Chad Rosier dabe2534ed [AArch64] Add integer pre- and post-index halfword/byte loads and stores.
llvm-svn: 248817
2015-09-29 18:26:15 +00:00
Kostya Serebryany 0c3a5767d9 [sanitizer] Fix Clang-tidy modernize-use-nullptr warnings in lib/sanitizer_common headers, unify closing inclusion guards. Patch by Eugene Zelenko
llvm-svn: 248816
2015-09-29 18:23:36 +00:00
Nemanja Ivanovic a0deee530b Forgot to remove a FIXME that has been fixed. NFC.
llvm-svn: 248815
2015-09-29 18:20:59 +00:00
Dehao Chen 028e122ca9 Revert r248810 which breaks tests.
llvm-svn: 248814
2015-09-29 18:18:49 +00:00
Nemanja Ivanovic 236904ea9e Addition of interfaces the FE to conform to Table A-2 of ELF V2 ABI V1.1
This patch corresponds to review:
http://reviews.llvm.org/D13190

Implemented the following interfaces to conform to ELF V2 ABI version 1.1.

vector signed __int128 vec_adde (vector signed __int128, vector signed __int128, vector signed __int128);
vector unsigned __int128 vec_adde (vector unsigned __int128, vector unsigned __int128, vector unsigned __int128);
vector signed __int128 vec_addec (vector signed __int128, vector signed __int128, vector signed __int128);
vector unsigned __int128 vec_addec (vector unsigned __int128, vector unsigned __int128, vector unsigned __int128);
vector signed int vec_addc(vector signed int __a, vector signed int __b);
vector bool char vec_cmpge (vector signed char __a, vector signed char __b);
vector bool char vec_cmpge (vector unsigned char __a, vector unsigned char __b);
vector bool short vec_cmpge (vector signed short __a, vector signed short __b);
vector bool short vec_cmpge (vector unsigned short __a, vector unsigned short __b);
vector bool int vec_cmpge (vector signed int __a, vector signed int __b);
vector bool int vec_cmpge (vector unsigned int __a, vector unsigned int __b);
vector bool char vec_cmple (vector signed char __a, vector signed char __b);
vector bool char vec_cmple (vector unsigned char __a, vector unsigned char __b);
vector bool short vec_cmple (vector signed short __a, vector signed short __b);
vector bool short vec_cmple (vector unsigned short __a, vector unsigned short __b);
vector bool int vec_cmple (vector signed int __a, vector signed int __b);
vector bool int vec_cmple (vector unsigned int __a, vector unsigned int __b);
vector double vec_double (vector signed long long __a);
vector double vec_double (vector unsigned long long __a);
vector bool char vec_eqv(vector bool char __a, vector bool char __b);
vector bool short vec_eqv(vector bool short __a, vector bool short __b);
vector bool int vec_eqv(vector bool int __a, vector bool int __b);
vector bool long long vec_eqv(vector bool long long __a, vector bool long long __b);
vector signed short vec_madd(vector signed short __a, vector signed short __b, vector signed short __c);
vector signed short vec_madd(vector signed short __a, vector unsigned short __b, vector unsigned short __c);
vector signed short vec_madd(vector unsigned short __a, vector signed short __b, vector signed short __c);
vector unsigned short vec_madd(vector unsigned short __a, vector unsigned short __b, vector unsigned short __c);
vector bool long long vec_mergeh(vector bool long long __a, vector bool long long __b);
vector bool long long vec_mergel(vector bool long long __a, vector bool long long __b);
vector bool char vec_nand(vector bool char __a, vector bool char __b);
vector bool short vec_nand(vector bool short __a, vector bool short __b);
vector bool int vec_nand(vector bool int __a, vector bool int __b);
vector bool long long vec_nand(vector bool long long __a, vector bool long long __b);
vector bool char vec_orc(vector bool char __a, vector bool char __b);
vector bool short vec_orc(vector bool short __a, vector bool short __b);
vector bool int vec_orc(vector bool int __a, vector bool int __b);
vector bool long long vec_orc(vector bool long long __a, vector bool long long __b);
vector signed long long vec_sub(vector signed long long __a, vector signed long long __b);
vector signed long long vec_sub(vector bool long long __a, vector signed long long __b);
vector signed long long vec_sub(vector signed long long __a, vector bool long long __b);
vector unsigned long long vec_sub(vector unsigned long long __a, vector unsigned long long __b);
vector unsigned long long vec_sub(vector bool long long __a, vector unsigned long long __b);
vector unsigned long long vec_sub(vector unsigned long long __V2 ABI V1.1


http://ror float vec_sub(vector float __a, vector float __b);
unsigned char vec_extract(vector bool char __a, int __b);
signed short vec_extract(vector signed short __a, int __b);
unsigned short vec_extract(vector bool short __a, int __b);
signed int vec_extract(vector signed int __a, int __b);
unsigned int vec_extract(vector bool int __a, int __b);
signed long long vec_extract(vector signed long long __a, int __b);
unsigned long long vec_extract(vector unsigned long long __a, int __b);
unsigned long long vec_extract(vector bool long long __a, int __b);
double vec_extract(vector double __a, int __b);
vector bool char vec_insert(unsigned char __a, vector bool char __b, int __c);
vector signed short vec_insert(signed short __a, vector signed short __b, int __c);
vector bool short vec_insert(unsigned short __a, vector bool short __b, int __c);
vector signed int vec_insert(signed int __a, vector signed int __b, int __c);
vector bool int vec_insert(unsigned int __a, vector bool int __b, int __c);
vector signed long long vec_insert(signed long long __a, vector signed long long __b, int __c);
vector unsigned long long vec_insert(unsigned long long __a, vector unsigned long long __b, int __c);
vector bool long long vec_insert(unsigned long long __a, vector bool long long __b, int __c);
vector double vec_insert(double __a, vector double __b, int __c);
vector signed long long vec_splats(signed long long __a);
vector unsigned long long vec_splats(unsigned long long __a);
vector signed __int128 vec_splats(signed __int128 __a);
vector unsigned __int128 vec_splats(unsigned __int128 __a);
vector double vec_splats(double __a);
int vec_all_eq(vector double __a, vector double __b);
int vec_all_ge(vector double __a, vector double __b);
int vec_all_gt(vector double __a, vector double __b);
int vec_all_le(vector double __a, vector double __b);
int vec_all_lt(vector double __a, vector double __b);
int vec_all_nan(vector double __a);
int vec_all_ne(vector double __a, vector double __b);
int vec_all_nge(vector double __a, vector double __b);
int vec_all_ngt(vector double __a, vector double __b);
int vec_any_eq(vector double __a, vector double __b);
int vec_any_ge(vector double __a, vector double __b);
int vec_any_gt(vector double __a, vector double __b);
int vec_any_le(vector double __a, vector double __b);
int vec_any_lt(vector double __a, vector double __b);
int vec_any_ne(vector double __a, vector double __b);
vector unsigned char vec_sbox_be (vector unsigned char);
vector unsigned char vec_cipher_be (vector unsigned char, vector unsigned char);
vector unsigned char vec_cipherlast_be (vector unsigned char, vector unsigned char);
vector unsigned char vec_ncipher_be (vector unsigned char, vector unsigned char);
vector unsigned char vec_ncipherlast_be (vector unsigned char, vector unsigned char);
vector unsigned int vec_shasigma_be (vector unsigned int, const int, const int);
vector unsigned long long vec_shasigma_be (vector unsigned long long, const int, const int);
vector unsigned short vec_pmsum_be (vector unsigned char, vector unsigned char);
vector unsigned int vec_pmsum_be (vector unsigned short, vector unsigned short);
vector unsigned long long vec_pmsum_be (vector unsigned int, vector unsigned int);
vector unsigned __int128 vec_pmsum_be (vector unsigned long long, vector unsigned long long);
vector unsigned char vec_gb (vector unsigned char);
vector unsigned long long vec_bperm (vector unsigned __int128 __a, vector unsigned char __b);

Removed the folowing interfaces either because their signatures have changed
in version 1.1 of the ABI or because they were implemented for ELF V2 ABI but
have actually been deprecated in version 1.1.

vector signed char vec_eqv(vector bool char __a, vector signed char __b);
vector signed char vec_eqv(vector signed char __a, vector bool char __b);
vector unsigned char vec_eqv(vector bool char __a, vector unsigned char __b);
vector unsigned char vec_eqv(vector unsigned char __a, vector bool char __b);
vector signed short vec_eqv(vector bool short __a, vector signed short __b);
vector signed short vec_eqv(vector signed short __a, vector bool short __b);
vector unsigned short vec_eqv(vector bool short __a, vector unsigned short __b);
vector unsigned short vec_eqv(vector unsigned short __a, vector bool short __b);
vector signed int vec_eqv(vector bool int __a, vector signed int __b);
vector signed int vec_eqv(vector signed int __a, vector bool int __b);
vector unsigned int vec_eqv(vector bool int __a, vector unsigned int __b);
vector unsigned int vec_eqv(vector unsigned int __a, vector bool int __b);
vector signed long long vec_eqv(vector bool long long __a, vector signed long long __b);
vector signed long long vec_eqv(vector signed long long __a, vector bool long long __b);
vector unsigned long long vec_eqv(vector bool long long __a, vector unsigned long long __b);
vector unsigned long long vec_eqv(vector unsigned long long __a, vector bool long long __b);
vector float vec_eqv(vector bool int __a, vector float __b);
vector float vec_eqv(vector float __a, vector bool int __b);
vector double vec_eqv(vector bool long long __a, vector double __b);
vector double vec_eqv(vector double __a, vector bool long long __b);
vector unsigned short vec_nand(vector bool short __a, vector unsigned short __b);

llvm-svn: 248813
2015-09-29 18:13:34 +00:00
Tobias Grosser 7dce3a60f2 Add default region generator
This hopefully helps to to address the following compile error on our buildbots

BlockGenerators.h:683:7: error: looser throw specifier for ‘virtual
polly::RegionGenerator::~RegionGenerator()’
BlockGenerators.h:164:11: error:   overriding ‘virtual polly::BlockGenerator::~BlockGenerator() noexcept
(true)`

llvm-svn: 248812
2015-09-29 18:07:17 +00:00
Hans Wennborg cc9deb4801 Fix Clang-tidy modernize-use-nullptr warnings in examples and include directories; other minor cleanups.
Patch by Eugene Zelenko!

Differential Revision: http://reviews.llvm.org/D13172

llvm-svn: 248811
2015-09-29 18:02:48 +00:00
Dehao Chen 410a25aa7a http://reviews.llvm.org/D13231
Change lookup functions to const functions.

llvm-svn: 248810
2015-09-29 17:59:58 +00:00
Nemanja Ivanovic 2c84b29464 Addition of interfaces the BE to conform to Table A-2 of ELF V2 ABI V1.1
This patch corresponds to review:
http://reviews.llvm.org/D13191

Back end portion of the fifth round of additions to altivec.h.

llvm-svn: 248809
2015-09-29 17:41:53 +00:00
Aaron Ballman 9d21454c16 Added MSVC natvis visualizers for Type and QualType. These could probably be improved, but anything is better than staring at hex values in the debugger.
llvm-svn: 248808
2015-09-29 17:32:36 +00:00
Yaron Keren 716f3a68c9 Fix typo.
llvm-svn: 248807
2015-09-29 16:51:08 +00:00
Rui Ueyama 9d4c6d771b [ELF2] Implemented --entry flag.
Patch from George Rimar!

llvm-svn: 248806
2015-09-29 16:40:13 +00:00
DeLesley Hutchins 2b504dce14 Thread Safety Analysis: allow capability attribute on unions.
llvm-svn: 248805
2015-09-29 16:24:18 +00:00
Chad Rosier 32d4d37e61 [AArch64] Scale offsets by the size of the memory operation. NFC.
The immediate in the load/store should be scaled by the size of the memory
operation, not the size of the register being loaded/stored.  This change gets
us one step closer to forming LDPSW instructions.  This change also enables
pre- and post-indexing for halfword and byte loads and stores.

llvm-svn: 248804
2015-09-29 16:07:32 +00:00
DeLesley Hutchins dc0541f12f Thread Safety Analysis: fix before/after checks so that they work on global
variables as well member variables.

llvm-svn: 248803
2015-09-29 15:25:51 +00:00
Daniel Jasper c1bc38ed4f clang-format: Add a new brace style "custom" as well as flags to
control the individual braces. The existing choices for brace wrapping
are now merely presets for the different flags that get expanded upon
calling the reformat function.

All presets have been chose to keep the existing formatting, so there
shouldn't be any difference in formatting behavior.

Also change the dump_format_style.py to properly document the nested
structs that are used to keep these flags discoverable among all the
configuration flags.

llvm-svn: 248802
2015-09-29 14:57:55 +00:00
Igor Laevsky cea9ede74e [ValueTracking] Lower dom-conditions-dom-blocks and dom-conditions-max-uses thresholds
On some of our benchmarks this change shows about 50% compile time improvement without any noticeable performance difference.

Differential Revision: http://reviews.llvm.org/D13248

llvm-svn: 248801
2015-09-29 14:57:52 +00:00
Chad Rosier a4d3217e81 [AArch64] Remove some redundant cases. NFC.
llvm-svn: 248800
2015-09-29 14:57:10 +00:00
Rafael Espindola 8acb95c7ab Add support for R_386_GOT32.
llvm-svn: 248799
2015-09-29 14:42:37 +00:00
John Brawn c23801d311 [CMake] Move the setting of LLVM_COMPILER_IS_GCC_COMPATIBLE to a separate file
Currently LLVM_COMPILER_IS_GCC_COMPATIBLE is set as a side-effect of determining
the stdlib to use in HandleLLVMStdlib, which causes problems when attempting to
use AddLLVM from an installed LLVM toolchain, as HandleLLVMStdlib is not used.
Move the setting of this variable into DetermineGCCCompatible and include that
from both AddLLVM and HandleLLVMStdlib.

Differential Revision: http://reviews.llvm.org/D13216

llvm-svn: 248798
2015-09-29 14:33:58 +00:00
Aaron Ballman 0f28d62a12 Some of the build bots are unhappy about the overload of the global operator new() because it was accidentally marked noexcept instead of noexcept(false). This should correct those bots.
llvm-svn: 248797
2015-09-29 14:26:00 +00:00
James Molloy 897048bee3 [ValueTracking] Teach isKnownNonZero about monotonically increasing PHIs
If a PHI starts at a non-negative constant, monotonically increases
(only adds of a constant are supported at the moment) and that add
does not wrap, then the PHI is known never to be zero.

llvm-svn: 248796
2015-09-29 14:08:45 +00:00
Rafael Espindola be901e2dbc Don't apply a relocation if we create a dynamic reloc.
With RELA that is just wasteful, with REL the relocation gets applied
twice.

llvm-svn: 248795
2015-09-29 13:51:43 +00:00
Aaron Ballman 5edd83de91 Silencing bot failures a more creative and definitive way.
llvm-svn: 248794
2015-09-29 13:38:00 +00:00
Rafael Espindola 6d7fcdb518 Add R_386_GOTPC support.
llvm-svn: 248793
2015-09-29 13:36:32 +00:00
Aaron Ballman 872c95c26f Hopefully silencing some built bot warnings. Note, this should be unsigned long instead of unsigned int, but then *other* builds start to fail because of duplicate redefinitions of size_t.
llvm-svn: 248792
2015-09-29 13:20:26 +00:00
Aaron Ballman de34985caa Adding a checker (misc-new-delete-overloads) that detects mismatched overloads of operator new and operator delete. Corresponds to the CERT C++ secure coding rule: https://www.securecoding.cert.org/confluence/display/cplusplus/DCL54-CPP.+Overload+allocation+and+deallocation+functions+as+a+pair+in+the+same+scope
llvm-svn: 248791
2015-09-29 13:12:21 +00:00
Pavel Labath 4a7436fd82 Enable test_create_after_attach_with_dwarf_and_popen on linux
The test still remains XTIMEOUTed. Will remove that as well if it turns out its passing.

llvm-svn: 248790
2015-09-29 12:42:56 +00:00
Tamas Berghammer 9d8dde8ce5 Change oat symbolization code for android to work on non-rooted devices
On android when debugging an apk we run lldb-server as application user
because the sell user (on non-rooted device) can't attach to an
application. The problem is that "adb pull" will run as a shell user
what can't access to files created by lldb-server because they will be
owned by the application user. This CL changes the oat symbolization
code to run "oatdump --symbolize" to generate an output what is owned
by the shell user.

Differential revision: http://reviews.llvm.org/D13162

llvm-svn: 248788
2015-09-29 11:04:18 +00:00
Jeroen Ketema 740f9d79ca Arguments spilled on the stack before a function call may have
alignment requirements, for example in the case of vectors.
These requirements are exploited by the code generator by using
move instructions that have similar alignment requirements, e.g.,
movaps on x86.

Although the code generator properly aligns the arguments with
respect to the displacement of the stack pointer it computes,
the displacement itself may cause misalignment. For example if
we have

%3 = load <16 x float>, <16 x float>* %1, align 64
call void @bar(<16 x float> %3, i32 0)

the x86 back-end emits:

movaps  32(%ecx), %xmm2
movaps  (%ecx), %xmm0
movaps  16(%ecx), %xmm1
movaps  48(%ecx), %xmm3
subl    $20, %esp       <-- if %esp was 16-byte aligned before this instruction, it no longer will be afterwards 
movaps  %xmm3, (%esp)   <-- movaps requires 16-byte alignment, while %esp is not aligned as such.
movl    $0, 16(%esp)
calll   __bar

To solve this, we need to make sure that the computed value with which
the stack pointer is changed is a multiple af the maximal alignment seen
during its computation. With this change we get proper alignment:

subl    $32, %esp
movaps  %xmm3, (%esp)

Differential Revision: http://reviews.llvm.org/D12337

llvm-svn: 248786
2015-09-29 10:12:57 +00:00
Angel Garcia Gomez 26fd0e8b62 Create modernize-make-unique check.
Summary: create a check that replaces 'std::unique_ptr<type>(new type(args...))' with 'std::make_unique<type>(args...)'. It was on the list of "Ideas for new Tools". It needs to be tested more carefully, but first I wanted to know if you think it is worth the effort.

Reviewers: klimek

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D13166

llvm-svn: 248785
2015-09-29 09:36:41 +00:00
Simon Pilgrim 43f5e0848e [InstCombine] Improve Vector Demanded Bits Through Bitcasts
Currently SimplifyDemandedVectorElts can only peek through bitcasts if the vectors have the same number of elements.

This patch fixes and enables some existing (disabled) code to support bitcasting to vectors with more/fewer elements. It currently only accepts cases when vectors alias cleanly (i.e. number of elements are an exact multiple of the other vector).

This was added to improve the demanded vector elements support for SSE vector shifts which require the __m128i (<2 x i64>) argument type to be bitcast to the vector type for the builtin shift. I've added extra tests for various additional bitcasts.

Differential Revision: http://reviews.llvm.org/D12935

llvm-svn: 248784
2015-09-29 08:19:11 +00:00
Dan Gohman 868e1c08d9 [WebAssembly] Rename test files to match platform naming conventions.
llvm-svn: 248783
2015-09-29 08:13:58 +00:00
Daniel Jasper 85c472dccd clang-format: Extend #include sorting functionality
Recognize the main module header as well as different #include categories.
This should now mimic the behavior of llvm/utils/sort_includes.py as
well as clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp very
closely.

llvm-svn: 248782
2015-09-29 07:53:08 +00:00
Tobias Grosser 98b3ee50ff Codegen: Support memory accesses with different types
Every once in a while we see code that accesses memory with different types,
e.g. to perform operations on a piece of memory using type 'float', but to copy
data to this memory using type 'int'. Modeled in C, such codes look like:

    void foo(float A[], float B[]) {
      for (long i = 0; i < 100; i++)
        *(int *)(&A[i]) = *(int *)(&B[i]);
      for (long i = 0; i < 100; i++)
        A[i] += 10;
    }

We already used the correct types during normal operations, but fall back to our
detected type as soon as we import changed memory access functions. For these
memory accesses we may generate invalid IR due to a mismatch between the element
type of the array we detect and the actual type used in the memory access.  To
address this issue, we always cast the newly created address of a memory access
back to the type of the memory access where the address will be used.

llvm-svn: 248781
2015-09-29 06:44:38 +00:00